|
104 | 104 | }
|
105 | 105 |
|
106 | 106 | const { getOptionValue } = NativeModule.require('internal/options');
|
107 |
| - const helpOption = getOptionValue('--help'); |
108 |
| - const completionBashOption = getOptionValue('--completion-bash'); |
109 |
| - const experimentalModulesOption = getOptionValue('--experimental-modules'); |
110 |
| - const experimentalVMModulesOption = |
111 |
| - getOptionValue('--experimental-vm-modules'); |
112 |
| - const experimentalWorkerOption = getOptionValue('--experimental-worker'); |
113 |
| - if (helpOption) { |
| 107 | + |
| 108 | + if (getOptionValue('--help')) { |
114 | 109 | NativeModule.require('internal/print_help').print(process.stdout);
|
115 | 110 | return;
|
116 | 111 | }
|
117 | 112 |
|
118 |
| - if (completionBashOption) { |
| 113 | + if (getOptionValue('--completion-bash')) { |
119 | 114 | NativeModule.require('internal/bash_completion').print(process.stdout);
|
120 | 115 | return;
|
121 | 116 | }
|
|
135 | 130 | setupQueueMicrotask();
|
136 | 131 | }
|
137 | 132 |
|
138 |
| - if (experimentalWorkerOption) { |
| 133 | + if (getOptionValue('--experimental-worker')) { |
139 | 134 | setupDOMException();
|
140 | 135 | }
|
141 | 136 |
|
|
167 | 162 | 'DeprecationWarning', 'DEP0062', startup, true);
|
168 | 163 | }
|
169 | 164 |
|
170 |
| - if (experimentalModulesOption || experimentalVMModulesOption) { |
171 |
| - if (experimentalModulesOption) { |
| 165 | + const experimentalModules = getOptionValue('--experimental-modules'); |
| 166 | + const experimentalVMModules = getOptionValue('--experimental-vm-modules'); |
| 167 | + if (experimentalModules || experimentalVMModules) { |
| 168 | + if (experimentalModules) { |
172 | 169 | process.emitWarning(
|
173 | 170 | 'The ESM module loader is experimental.',
|
174 | 171 | 'ExperimentalWarning', undefined);
|
|
228 | 225 |
|
229 | 226 | setupAllowedFlags();
|
230 | 227 |
|
231 |
| - // There are various modes that Node can run in. The most common two |
232 |
| - // are running from a script and running the REPL - but there are a few |
233 |
| - // others like the debugger or running --eval arguments. Here we decide |
234 |
| - // which mode we run in. |
| 228 | + startExecution(); |
| 229 | + } |
| 230 | + |
| 231 | + // There are various modes that Node can run in. The most common two |
| 232 | + // are running from a script and running the REPL - but there are a few |
| 233 | + // others like the debugger or running --eval arguments. Here we decide |
| 234 | + // which mode we run in. |
| 235 | + function startExecution() { |
| 236 | + // This means we are in a Worker context, and any script execution |
| 237 | + // will be directed by the worker module. |
235 | 238 | if (internalBinding('worker').getEnvMessagePort() !== undefined) {
|
236 |
| - // This means we are in a Worker context, and any script execution |
237 |
| - // will be directed by the worker module. |
238 | 239 | NativeModule.require('internal/worker').setupChild(evalScript);
|
239 |
| - } else if (NativeModule.exists('_third_party_main')) { |
240 |
| - // To allow people to extend Node in different ways, this hook allows |
241 |
| - // one to drop a file lib/_third_party_main.js into the build |
242 |
| - // directory which will be executed instead of Node's normal loading. |
| 240 | + return; |
| 241 | + } |
| 242 | + |
| 243 | + // To allow people to extend Node in different ways, this hook allows |
| 244 | + // one to drop a file lib/_third_party_main.js into the build |
| 245 | + // directory which will be executed instead of Node's normal loading. |
| 246 | + if (NativeModule.exists('_third_party_main')) { |
243 | 247 | process.nextTick(() => {
|
244 | 248 | NativeModule.require('_third_party_main');
|
245 | 249 | });
|
246 |
| - } else if (process.argv[1] === 'inspect' || process.argv[1] === 'debug') { |
| 250 | + return; |
| 251 | + } |
| 252 | + |
| 253 | + // `node inspect ...` or `node debug ...` |
| 254 | + if (process.argv[1] === 'inspect' || process.argv[1] === 'debug') { |
247 | 255 | if (process.argv[1] === 'debug') {
|
248 | 256 | process.emitWarning(
|
249 | 257 | '`node debug` is deprecated. Please use `node inspect` instead.',
|
|
254 | 262 | process.nextTick(() => {
|
255 | 263 | NativeModule.require('internal/deps/node-inspect/lib/_inspect').start();
|
256 | 264 | });
|
| 265 | + return; |
| 266 | + } |
257 | 267 |
|
258 |
| - } else if (process.profProcess) { |
| 268 | + // `node --prof-process` |
| 269 | + // TODO(joyeecheung): use internal/options instead of process.profProcess |
| 270 | + if (process.profProcess) { |
259 | 271 | NativeModule.require('internal/v8_prof_processor');
|
260 |
| - } else { |
261 |
| - // There is user code to be run. |
262 |
| - |
263 |
| - // If this is a worker in cluster mode, start up the communication |
264 |
| - // channel. This needs to be done before any user code gets executed |
265 |
| - // (including preload modules). |
266 |
| - if (process.argv[1] && process.env.NODE_UNIQUE_ID) { |
267 |
| - const cluster = NativeModule.require('cluster'); |
268 |
| - cluster._setupWorker(); |
269 |
| - // Make sure it's not accidentally inherited by child processes. |
270 |
| - delete process.env.NODE_UNIQUE_ID; |
| 272 | + return; |
| 273 | + } |
| 274 | + |
| 275 | + // There is user code to be run. |
| 276 | + prepareUserCodeExecution(); |
| 277 | + executeUserCode(); |
| 278 | + } |
| 279 | + |
| 280 | + function prepareUserCodeExecution() { |
| 281 | + // If this is a worker in cluster mode, start up the communication |
| 282 | + // channel. This needs to be done before any user code gets executed |
| 283 | + // (including preload modules). |
| 284 | + if (process.argv[1] && process.env.NODE_UNIQUE_ID) { |
| 285 | + const cluster = NativeModule.require('cluster'); |
| 286 | + cluster._setupWorker(); |
| 287 | + // Make sure it's not accidentally inherited by child processes. |
| 288 | + delete process.env.NODE_UNIQUE_ID; |
| 289 | + } |
| 290 | + |
| 291 | + // For user code, we preload modules if `-r` is passed |
| 292 | + // TODO(joyeecheung): use internal/options instead of |
| 293 | + // process._preload_modules |
| 294 | + if (process._preload_modules) { |
| 295 | + const { |
| 296 | + _preloadModules |
| 297 | + } = NativeModule.require('internal/modules/cjs/loader'); |
| 298 | + _preloadModules(process._preload_modules); |
| 299 | + } |
| 300 | + } |
| 301 | + |
| 302 | + function executeUserCode() { |
| 303 | + // User passed `-e` or `--eval` arguments to Node without `-i` or |
| 304 | + // `--interactive`. |
| 305 | + // Note that the name `forceRepl` is merely an alias of `interactive` |
| 306 | + // in code. |
| 307 | + // TODO(joyeecheung): use internal/options instead of |
| 308 | + // process._eval/process._forceRepl |
| 309 | + if (process._eval != null && !process._forceRepl) { |
| 310 | + const { |
| 311 | + addBuiltinLibsToObject |
| 312 | + } = NativeModule.require('internal/modules/cjs/helpers'); |
| 313 | + addBuiltinLibsToObject(global); |
| 314 | + evalScript('[eval]', wrapForBreakOnFirstLine(process._eval)); |
| 315 | + return; |
| 316 | + } |
| 317 | + |
| 318 | + // If the first argument is a file name, run it as a main script |
| 319 | + if (process.argv[1] && process.argv[1] !== '-') { |
| 320 | + // Expand process.argv[1] into a full path. |
| 321 | + const path = NativeModule.require('path'); |
| 322 | + process.argv[1] = path.resolve(process.argv[1]); |
| 323 | + |
| 324 | + const CJSModule = NativeModule.require('internal/modules/cjs/loader'); |
| 325 | + |
| 326 | + // If user passed `-c` or `--check` arguments to Node, check its syntax |
| 327 | + // instead of actually running the file. |
| 328 | + // TODO(joyeecheung): use internal/options instead of |
| 329 | + // process._syntax_check_only |
| 330 | + if (process._syntax_check_only != null) { |
| 331 | + const fs = NativeModule.require('fs'); |
| 332 | + // Read the source. |
| 333 | + const filename = CJSModule._resolveFilename(process.argv[1]); |
| 334 | + const source = fs.readFileSync(filename, 'utf-8'); |
| 335 | + checkScriptSyntax(source, filename); |
| 336 | + process.exit(0); |
271 | 337 | }
|
272 | 338 |
|
273 |
| - if (process._eval != null && !process._forceRepl) { |
274 |
| - // User passed '-e' or '--eval' arguments to Node without '-i' or |
275 |
| - // '--interactive'. |
276 |
| - preloadModules(); |
277 |
| - |
278 |
| - const { |
279 |
| - addBuiltinLibsToObject |
280 |
| - } = NativeModule.require('internal/modules/cjs/helpers'); |
281 |
| - addBuiltinLibsToObject(global); |
282 |
| - evalScript('[eval]'); |
283 |
| - } else if (process.argv[1] && process.argv[1] !== '-') { |
284 |
| - // Make process.argv[1] into a full path. |
285 |
| - const path = NativeModule.require('path'); |
286 |
| - process.argv[1] = path.resolve(process.argv[1]); |
287 |
| - |
288 |
| - const CJSModule = NativeModule.require('internal/modules/cjs/loader'); |
289 |
| - |
290 |
| - preloadModules(); |
291 |
| - // Check if user passed `-c` or `--check` arguments to Node. |
292 |
| - if (process._syntax_check_only != null) { |
293 |
| - const fs = NativeModule.require('fs'); |
294 |
| - // Read the source. |
295 |
| - const filename = CJSModule._resolveFilename(process.argv[1]); |
296 |
| - const source = fs.readFileSync(filename, 'utf-8'); |
297 |
| - checkScriptSyntax(source, filename); |
298 |
| - process.exit(0); |
| 339 | + // Note: this actually tries to run the module as a ESM first if |
| 340 | + // --experimental-modules is on. |
| 341 | + // TODO(joyeecheung): can we move that logic to here? Note that this |
| 342 | + // is an undocumented method available via `require('module').runMain` |
| 343 | + CJSModule.runMain(); |
| 344 | + return; |
| 345 | + } |
| 346 | + |
| 347 | + // Create the REPL if `-i` or `--interactive` is passed, or if |
| 348 | + // stdin is a TTY. |
| 349 | + // Note that the name `forceRepl` is merely an alias of `interactive` |
| 350 | + // in code. |
| 351 | + if (process._forceRepl || NativeModule.require('tty').isatty(0)) { |
| 352 | + const cliRepl = NativeModule.require('internal/repl'); |
| 353 | + cliRepl.createInternalRepl(process.env, (err, repl) => { |
| 354 | + if (err) { |
| 355 | + throw err; |
299 | 356 | }
|
300 |
| - CJSModule.runMain(); |
301 |
| - } else { |
302 |
| - preloadModules(); |
303 |
| - // If -i or --interactive were passed, or stdin is a TTY. |
304 |
| - if (process._forceRepl || NativeModule.require('tty').isatty(0)) { |
305 |
| - // REPL |
306 |
| - const cliRepl = NativeModule.require('internal/repl'); |
307 |
| - cliRepl.createInternalRepl(process.env, (err, repl) => { |
308 |
| - if (err) { |
309 |
| - throw err; |
310 |
| - } |
311 |
| - repl.on('exit', () => { |
312 |
| - if (repl._flushing) { |
313 |
| - repl.pause(); |
314 |
| - return repl.once('flushHistory', () => { |
315 |
| - process.exit(); |
316 |
| - }); |
317 |
| - } |
| 357 | + repl.on('exit', () => { |
| 358 | + if (repl._flushing) { |
| 359 | + repl.pause(); |
| 360 | + return repl.once('flushHistory', () => { |
318 | 361 | process.exit();
|
319 | 362 | });
|
320 |
| - }); |
321 |
| - |
322 |
| - if (process._eval != null) { |
323 |
| - // User passed '-e' or '--eval' |
324 |
| - evalScript('[eval]'); |
325 | 363 | }
|
326 |
| - } else { |
327 |
| - // Read all of stdin - execute it. |
328 |
| - process.stdin.setEncoding('utf8'); |
329 |
| - |
330 |
| - let code = ''; |
331 |
| - process.stdin.on('data', (d) => { |
332 |
| - code += d; |
333 |
| - }); |
334 |
| - |
335 |
| - process.stdin.on('end', function() { |
336 |
| - if (process._syntax_check_only != null) { |
337 |
| - checkScriptSyntax(code, '[stdin]'); |
338 |
| - } else { |
339 |
| - process._eval = code; |
340 |
| - evalScript('[stdin]'); |
341 |
| - } |
342 |
| - }); |
343 |
| - } |
| 364 | + process.exit(); |
| 365 | + }); |
| 366 | + }); |
| 367 | + |
| 368 | + // User passed '-e' or '--eval' along with `-i` or `--interactive` |
| 369 | + if (process._eval != null) { |
| 370 | + evalScript('[eval]', wrapForBreakOnFirstLine(process._eval)); |
344 | 371 | }
|
| 372 | + return; |
345 | 373 | }
|
| 374 | + |
| 375 | + // Stdin is not a TTY, we will read it and execute it. |
| 376 | + readAndExecuteStdin(); |
| 377 | + } |
| 378 | + |
| 379 | + function readAndExecuteStdin() { |
| 380 | + process.stdin.setEncoding('utf8'); |
| 381 | + |
| 382 | + let code = ''; |
| 383 | + process.stdin.on('data', (d) => { |
| 384 | + code += d; |
| 385 | + }); |
| 386 | + |
| 387 | + process.stdin.on('end', () => { |
| 388 | + if (process._syntax_check_only != null) { |
| 389 | + checkScriptSyntax(code, '[stdin]'); |
| 390 | + } else { |
| 391 | + process._eval = code; |
| 392 | + evalScript('[stdin]', wrapForBreakOnFirstLine(process._eval)); |
| 393 | + } |
| 394 | + }); |
346 | 395 | }
|
347 | 396 |
|
348 | 397 | function setupTraceCategoryState() {
|
|
651 | 700 | return `process.binding('inspector').callAndPauseOnStart(${fn}, {})`;
|
652 | 701 | }
|
653 | 702 |
|
654 |
| - function evalScript(name, body = wrapForBreakOnFirstLine(process._eval)) { |
| 703 | + function evalScript(name, body) { |
655 | 704 | const CJSModule = NativeModule.require('internal/modules/cjs/loader');
|
656 | 705 | const path = NativeModule.require('path');
|
657 | 706 | const cwd = tryGetCwd(path);
|
|
673 | 722 | process._tickCallback();
|
674 | 723 | }
|
675 | 724 |
|
676 |
| - // Load preload modules. |
677 |
| - function preloadModules() { |
678 |
| - if (process._preload_modules) { |
679 |
| - const { |
680 |
| - _preloadModules |
681 |
| - } = NativeModule.require('internal/modules/cjs/loader'); |
682 |
| - _preloadModules(process._preload_modules); |
683 |
| - } |
684 |
| - } |
685 |
| - |
686 | 725 | function checkScriptSyntax(source, filename) {
|
687 | 726 | const CJSModule = NativeModule.require('internal/modules/cjs/loader');
|
688 | 727 | const vm = NativeModule.require('vm');
|
|
0 commit comments