es-node-runner
Version:
Node runner that transpiles typescript or es modules using blazing fast ⚡ esbuild and restarts the process automatically on change. Suitable for node development server.
86 lines (85 loc) • 2.57 kB
JavaScript
import {build} from 'esbuild';
import DEBUG from 'debug';
import path from 'path';
import {writeFileSync} from 'fs';
import {performance} from 'perf_hooks';
import {buildOptions, spawnOptions} from './config.js';
import {restart, run} from './runner.js';
import {debounce, logger, resolveNodeModulePaths} from './utils/index.js';
const debug = DEBUG('es-node-runner:transpiler');
const lightning = process.stdout.isTTY ? '\u26A1' : '';
let buildResult;
const initialBuild = async () => {
debug('starting initial build');
const BUILD_START_TIME = performance.now();
const {entry, outdir, outfile, ...options} = buildOptions;
const output = path.join(outdir, outfile);
try {
buildResult = await build({
entryPoints: [entry],
allowOverwrite: true,
bundle: true,
platform: 'node',
incremental: true,
external: resolveNodeModulePaths(),
outfile: output,
...options,
});
logger.info(
`[Esbuild]: ${lightning} Build completed in ${(
performance.now() - BUILD_START_TIME
).toFixed(2)} ms\n`
);
debug('initial build completed');
} catch (error) {
debug('initial build failed');
throw error;
}
if (options.format === 'esm' && outdir.includes('node_modules')) {
writeFileSync(
path.join(outdir, 'package.json'),
JSON.stringify({type: 'module'}),
{encoding: 'utf-8'}
);
}
run([...spawnOptions.args, output]);
logger.success(
`[Sub Process]: Spawned in ${(
performance.now() - global.PROCESS_START_TIME
).toFixed(2)} ms\n`
);
};
const rebuild = debounce(
async () => {
debug('starting rebuild');
const REBUILD_START_TIME = performance.now();
if (buildResult.rebuild) {
try {
await buildResult.rebuild();
logger.info(
`[Esbuild]: ${lightning} Rebuild completed in ${(
performance.now() - REBUILD_START_TIME
).toFixed(2)} ms\n`
);
debug('rebuild completed');
restart();
logger.success(
`[Sub Process]: Respawned in ${(
performance.now() - global.SUB_PROCESS_RESTART_TIME
).toFixed(2)} ms\n`
);
} catch (error) {
debug('rebuild failed');
logger.error(error);
}
}
},
spawnOptions.autoRestart === false ? 0 : spawnOptions.delay
);
const dispose = () => {
debug('disposing build cache');
buildResult.rebuild?.dispose();
debug('build cache disposed');
logger.info('[Esbuild]: Build cache disposed\n');
};
export {initialBuild, rebuild, dispose};