UNPKG

node-dev

Version:

Restarts your app when files are modified

76 lines (61 loc) 2.73 kB
const { dirname, extname } = require('path'); const childProcess = require('child_process'); const { sync: resolve } = require('resolve'); const { isMainThread } = require('worker_threads'); const { getConfig } = require('./cfg'); const hook = require('./hook'); const { relay, send } = require('./ipc'); const resolveMain = require('./resolve-main'); const suppressExperimentalWarnings = require('./suppress-experimental-warnings'); // Experimental warnings need to be suppressed in worker threads as well, since // their process inherits the Node arguments from the main thread. suppressExperimentalWarnings(process); // When using worker threads, each thread appears to require this file through // the shared Node arguments (--require), so filter them out here and only run // on the main thread. if (!isMainThread) return; const script = process.argv[1]; const { extensions, fork, vm } = getConfig(script); if (process.env.NODE_DEV_PRELOAD) { require(process.env.NODE_DEV_PRELOAD); } // We want to exit on SIGTERM, but defer to existing SIGTERM handlers. process.once('SIGTERM', () => process.listenerCount('SIGTERM') || process.exit(0)); if (fork) { // Overwrite child_process.fork() so that we can hook into forked processes // too. We also need to relay messages about required files to the parent. const originalFork = childProcess.fork; childProcess.fork = (modulePath, args, options) => { const child = originalFork(modulePath, args, options); relay(child); return child; }; } // Error handler that displays a notification and logs the stack to stderr: process.on('uncaughtException', err => { // Sometimes uncaught exceptions are not errors const { message, name, stack } = err instanceof Error ? err : new Error(`uncaughtException ${err}`); console.error(stack); // If there's a custom uncaughtException handler expect it to terminate // the process. const willTerminate = process.listenerCount('uncaughtException') > 1; send({ error: name, message, willTerminate }); }); // Hook into require() and notify the parent process about required files hook(vm, required => send({ required })); // Check if a module is registered for this extension const main = resolveMain(script); const ext = extname(main).slice(1); const mod = extensions[ext]; const basedir = dirname(main); // Support extensions where 'require' returns a function that accepts options if (typeof mod === 'object' && mod.name) { const fn = require(resolve(mod.name, { basedir })); if (typeof fn === 'function' && mod.options) { // require returned a function, call it with options fn(mod.options); } } else if (typeof mod === 'string') { require(resolve(mod, { basedir })); }