133 lines
3.6 KiB
JavaScript
133 lines
3.6 KiB
JavaScript
import EventEmitter from 'events'
|
|
import { writeFileSync, existsSync } from 'fs'
|
|
import { join, resolve } from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
import { watch as _watch, rollup as _rollup } from 'rollup'
|
|
import loadAndParseConfigFile from 'rollup/dist/loadConfigFile.js'
|
|
|
|
import Builder from './Builder.js'
|
|
|
|
const __dirname = resolve(fileURLToPath(import.meta.url), '../')
|
|
|
|
const rootDir = join(__dirname, '../../../../')
|
|
const pkgJson = (await import(join(rootDir, 'package.json'), {
|
|
assert: {
|
|
type: "json",
|
|
}
|
|
})).default
|
|
|
|
export default class RollupBuilder extends Builder {
|
|
constructor ({ name = 'rollup', configPath = join(rootDir, 'rollup.config.js'), tempDir = join(rootDir, '.mocha-ts'), watch = false }) {
|
|
super(join(tempDir, 'semaphore'), name)
|
|
this.configPath = configPath
|
|
this.watch = watch
|
|
}
|
|
|
|
async start () {
|
|
await super.start()
|
|
|
|
const { options } = await loadAndParseConfigFile(this.configPath)
|
|
// Watch only the Node ESM module, that is the one we are going to use with mocha
|
|
const rollupOptions = options.filter(bundle => {
|
|
const file = (bundle.output[0].dir !== undefined)
|
|
? join(bundle.output[0].dir, bundle.output[0].entryFileNames)
|
|
: bundle.output[0].file
|
|
return file === join(rootDir, pkgJson.exports['.'].node.import)
|
|
})[0]
|
|
if (rollupOptions.output.length > 1) {
|
|
rollupOptions.output = rollupOptions.output[0]
|
|
}
|
|
|
|
this.builder = new RollupBundler(rollupOptions, this.watch)
|
|
|
|
this.builder.on('event', event => {
|
|
switch (event.code) {
|
|
case 'START':
|
|
this.emit('busy')
|
|
if (this.firstBuild === true) {
|
|
this.emit('message', 'building your module...')
|
|
} else {
|
|
this.emit('message', 'file changes detected. Rebuilding module files...')
|
|
}
|
|
break
|
|
|
|
case 'BUNDLE_END':
|
|
if (event.result) event.result.close()
|
|
break
|
|
|
|
case 'END':
|
|
if (event.result) event.result.close()
|
|
this.emit('ready')
|
|
break
|
|
|
|
case 'ERROR':
|
|
if (event.result) event.result.close()
|
|
this.emit('error', event.error)
|
|
writeFileSync(join(rootDir, pkgJson.exports['.'].node.import), '', 'utf8')
|
|
this.emit('ready')
|
|
break
|
|
|
|
default:
|
|
this.emit('busy')
|
|
break
|
|
}
|
|
})
|
|
|
|
this.builder.start()
|
|
|
|
return await this.ready()
|
|
}
|
|
|
|
async close () {
|
|
await super.close()
|
|
this.builder.close()
|
|
}
|
|
}
|
|
|
|
class RollupBundler extends EventEmitter {
|
|
constructor (rollupOptions, watch = false) {
|
|
super()
|
|
this.rollupOptions = rollupOptions
|
|
this.watch = watch
|
|
}
|
|
|
|
async start () {
|
|
if (this.watch === true) {
|
|
this.watcher = _watch(this.rollupOptions)
|
|
|
|
this.watcher.on('event', event => {
|
|
this.emit('event', event)
|
|
})
|
|
} else {
|
|
if (existsSync(join(rootDir, pkgJson.exports['.'].node.import)) === false) {
|
|
await this._bundle()
|
|
} else {
|
|
this.emit('event', { code: 'END', noBuild: true })
|
|
}
|
|
}
|
|
}
|
|
|
|
async _bundle () {
|
|
this.emit('event', { code: 'START' })
|
|
for (const optionsObj of [].concat(this.rollupOptions)) {
|
|
try {
|
|
const bundle = await _rollup(optionsObj)
|
|
try {
|
|
await Promise.all(optionsObj.output.map(bundle.write))
|
|
this.emit('event', { code: 'BUNDLE_END' })
|
|
} catch (error) {
|
|
this.emit('event', { code: 'ERROR', error })
|
|
}
|
|
} catch (error) {
|
|
this.emit('event', { code: 'ERROR', error })
|
|
}
|
|
}
|
|
this.emit('event', { code: 'END' })
|
|
}
|
|
|
|
close () {
|
|
if (this.watcher !== undefined) this.watcher.close()
|
|
}
|
|
}
|