diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index b537e62fe99d83..738cb51809b883 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -1,7 +1,7 @@ // Hello, and welcome to hacking node.js! // -// This file is invoked by node::LoadEnvironment in src/node.cc, and is -// responsible for bootstrapping the node.js core. As special caution is given +// This file is invoked by node::LoadEnvironment() in src/node.cc, and is +// responsible for bootstrapping the Node.js core. As special caution is given // to the performance of the startup process, many dependencies are invoked // lazily. // @@ -13,7 +13,7 @@ 'use strict'; // This file is compiled as if it's wrapped in a function with arguments -// passed by node::LoadEnvironment() +// passed by node::LoadEnvironment(). /* global process, bootstrappers, loaderExports, triggerFatalException */ const { _setupTraceCategoryState, @@ -27,8 +27,13 @@ const { } = bootstrappers; const { internalBinding, NativeModule } = loaderExports; +const configBinding = internalBinding('config'); +const workerBinding = internalBinding('worker'); +const internalUtil = NativeModule.require('internal/util'); +const util = NativeModule.require('util'); + const exceptionHandlerState = { captureFn: null }; -const isMainThread = internalBinding('worker').threadId === 0; +const isMainThread = workerBinding.threadId === 0; function startup() { setupTraceCategoryState(); @@ -42,11 +47,11 @@ function startup() { setupGlobalVariables(); - // Bootstrappers for all threads, including worker threads and main thread + // Bootstrappers for all threads, including worker threads and main thread. const perThreadSetup = NativeModule.require('internal/process/per_thread'); - // Bootstrappers for the main thread only + // Bootstrappers for the main thread only. let mainThreadSetup; - // Bootstrappers for the worker threads only + // Bootstrappers for the worker threads only. let workerThreadSetup; if (isMainThread) { mainThreadSetup = NativeModule.require( @@ -120,8 +125,7 @@ function startup() { mainThreadSetup.setupChildProcessIpcChannel(); } - const browserGlobals = !process._noBrowserGlobals; - if (browserGlobals) { + if (!process._noBrowserGlobals) { setupGlobalTimeouts(); setupGlobalConsole(); setupGlobalURL(); @@ -172,22 +176,22 @@ function startup() { NativeModule.require('internal/process/esm_loader').setup(); } - const { deprecate } = NativeModule.require('internal/util'); + const { deprecate } = internalUtil; { // Install legacy getters on the `util` binding for typechecking. // TODO(addaleax): Turn into a full runtime deprecation. - const { pendingDeprecation } = internalBinding('config'); + const { pendingDeprecation } = configBinding; const utilBinding = internalBinding('util'); const types = internalBinding('types'); for (const name of [ - 'isArrayBuffer', 'isArrayBufferView', 'isAsyncFunction', - 'isDataView', 'isDate', 'isExternal', 'isMap', 'isMapIterator', - 'isNativeError', 'isPromise', 'isRegExp', 'isSet', 'isSetIterator', - 'isTypedArray', 'isUint8Array', 'isAnyArrayBuffer' + 'isAnyArrayBuffer', 'isArrayBuffer', 'isArrayBufferView', + 'isAsyncFunction', 'isDataView', 'isDate', 'isExternal', 'isMap', + 'isMapIterator', 'isNativeError', 'isPromise', 'isRegExp', 'isSet', + 'isSetIterator', 'isTypedArray', 'isUint8Array' ]) { utilBinding[name] = pendingDeprecation ? deprecate(types[name], - 'Accessing native typechecking bindings of Node ' + + 'Accessing native typechecking bindings of Node.js ' + 'directly is deprecated. ' + `Please use \`util.types.${name}\` instead.`, 'DEP0103') : @@ -202,21 +206,21 @@ function startup() { startExecution(); } -// There are various modes that Node can run in. The most common two +// There are various modes that Node.js can run in. The most common two // are running from a script and running the REPL - but there are a few // others like the debugger or running --eval arguments. Here we decide // which mode we run in. function startExecution() { // This means we are in a Worker context, and any script execution // will be directed by the worker module. - if (internalBinding('worker').getEnvMessagePort() !== undefined) { + if (workerBinding.getEnvMessagePort() !== undefined) { NativeModule.require('internal/worker').setupChild(evalScript); return; } - // To allow people to extend Node in different ways, this hook allows + // To allow people to extend Node.js in different ways, this hook allows // one to drop a file lib/_third_party_main.js into the build - // directory which will be executed instead of Node's normal loading. + // directory which will be executed instead of Node.js' normal loading. if (NativeModule.exists('_third_party_main')) { process.nextTick(() => { NativeModule.require('_third_party_main'); @@ -224,9 +228,10 @@ function startExecution() { return; } - // `node inspect ...` or `node debug ...` - if (process.argv[1] === 'inspect' || process.argv[1] === 'debug') { - if (process.argv[1] === 'debug') { + // `node inspect ...` or `node debug ...`. + const argv1 = process.argv[1]; + if (argv1 === 'inspect' || argv1 === 'debug') { + if (argv1 === 'debug') { process.emitWarning( '`node debug` is deprecated. Please use `node inspect` instead.', 'DeprecationWarning', 'DEP0068'); @@ -239,8 +244,8 @@ function startExecution() { return; } - // `node --prof-process` - // TODO(joyeecheung): use internal/options instead of process.profProcess + // `node --prof-process`. + // TODO(joyeecheung): Use internal/options instead of process.profProcess. if (process.profProcess) { NativeModule.require('internal/v8_prof_processor'); return; @@ -262,9 +267,9 @@ function prepareUserCodeExecution() { delete process.env.NODE_UNIQUE_ID; } - // For user code, we preload modules if `-r` is passed - // TODO(joyeecheung): use internal/options instead of - // process._preload_modules + // For user code, we preload modules if `-r` is passed. + // TODO(joyeecheung): Use internal/options instead of + // process._preload_modules. if (process._preload_modules) { const { _preloadModules @@ -274,12 +279,12 @@ function prepareUserCodeExecution() { } function executeUserCode() { - // User passed `-e` or `--eval` arguments to Node without `-i` or + // User passed `-e` or `--eval` arguments to Node.js without `-i` or // `--interactive`. - // Note that the name `forceRepl` is merely an alias of `interactive` + // Note that the name `_forceRepl` is merely an alias of `interactive` // in code. - // TODO(joyeecheung): use internal/options instead of - // process._eval/process._forceRepl + // TODO(joyeecheung): Use internal/options instead of + // process._eval/process._forceRepl. if (process._eval != null && !process._forceRepl) { const { addBuiltinLibsToObject @@ -289,18 +294,19 @@ function executeUserCode() { return; } - // If the first argument is a file name, run it as a main script - if (process.argv[1] && process.argv[1] !== '-') { + // If the first argument is a file name, run it as a main script. + const argv1 = process.argv[1]; + if (argv1 && argv1 !== '-') { // Expand process.argv[1] into a full path. const path = NativeModule.require('path'); - process.argv[1] = path.resolve(process.argv[1]); + process.argv[1] = path.resolve(argv1); const CJSModule = NativeModule.require('internal/modules/cjs/loader'); - // If user passed `-c` or `--check` arguments to Node, check its syntax + // If user passed `-c` or `--check` arguments to Node.js, check its syntax // instead of actually running the file. - // TODO(joyeecheung): use internal/options instead of - // process._syntax_check_only + // TODO(joyeecheung): Use internal/options instead of + // process._syntax_check_only. if (process._syntax_check_only != null) { const fs = NativeModule.require('fs'); // Read the source. @@ -310,17 +316,16 @@ function executeUserCode() { process.exit(0); } - // Note: this actually tries to run the module as a ESM first if + // Note: this actually tries to run the module as an ESM first if // --experimental-modules is on. - // TODO(joyeecheung): can we move that logic to here? Note that this - // is an undocumented method available via `require('module').runMain` + // TODO(joyeecheung): Can we move that logic to here? Note that this + // is an undocumented method available via `require('module').runMain`. CJSModule.runMain(); return; } - // Create the REPL if `-i` or `--interactive` is passed, or if - // stdin is a TTY. - // Note that the name `forceRepl` is merely an alias of `interactive` + // Create the REPL if `-i` or `--interactive` is passed, or if stdin is a TTY. + // Note that the name `_forceRepl` is merely an alias of `interactive` // in code. if (process._forceRepl || NativeModule.require('tty').isatty(0)) { const cliRepl = NativeModule.require('internal/repl'); @@ -339,7 +344,7 @@ function executeUserCode() { }); }); - // User passed '-e' or '--eval' along with `-i` or `--interactive` + // User passed '-e' or '--eval' along with `-i` or `--interactive`. if (process._eval != null) { evalScript('[eval]', wrapForBreakOnFirstLine(process._eval)); } @@ -374,11 +379,11 @@ function setupTraceCategoryState() { let traceEventsAsyncHook; function toggleTraceCategoryState() { - // Dynamically enable/disable the traceEventsAsyncHook + // Dynamically enable/disable the traceEventsAsyncHook. const asyncHooksEnabled = !!traceCategoryState[kCategoryAsyncHooks]; if (asyncHooksEnabled) { - // Lazy load internal/trace_events_async_hooks only if the async_hooks + // Lazily load internal/trace_events_async_hooks only if the async_hooks // trace event category is enabled. if (!traceEventsAsyncHook) { traceEventsAsyncHook = @@ -409,7 +414,6 @@ function setupGlobalVariables() { configurable: true }); global.process = process; - const util = NativeModule.require('util'); function makeGetter(name) { return util.deprecate(function() { @@ -462,20 +466,18 @@ function setupGlobalTimeouts() { function setupGlobalConsole() { const consoleFromVM = global.console; - const consoleFromNode = - NativeModule.require('internal/console/global'); + const consoleFromNode = NativeModule.require('internal/console/global'); // Override global console from the one provided by the VM - // to the one implemented by Node.js + // to the one implemented by Node.js. Object.defineProperty(global, 'console', { configurable: true, enumerable: false, value: consoleFromNode, writable: true }); - // TODO(joyeecheung): can we skip this if inspector is not active? + // TODO(joyeecheung): Can we skip this if inspector is not active? if (process.config.variables.v8_enable_inspector) { - const inspector = - NativeModule.require('internal/console/inspector'); + const inspector = NativeModule.require('internal/console/inspector'); inspector.addInspectorApis(consoleFromNode, consoleFromVM); // This will be exposed by `require('inspector').console` later. inspector.consoleFromVM = consoleFromVM; @@ -501,16 +503,15 @@ function setupGlobalURL() { } function setupGlobalEncoding() { - const { TextEncoder, TextDecoder } = NativeModule.require('util'); Object.defineProperties(global, { TextEncoder: { - value: TextEncoder, + value: util.TextEncoder, writable: true, configurable: true, enumerable: false }, TextDecoder: { - value: TextDecoder, + value: util.TextDecoder, writable: true, configurable: true, enumerable: false @@ -574,7 +575,7 @@ function setupProcessFatal() { if (exceptionHandlerState.captureFn !== null) { exceptionHandlerState.captureFn(er); } else if (!process.emit('uncaughtException', er)) { - // If someone handled it, then great. otherwise, die in C++ land + // If someone handled it, then great. Otherwise, die in C++ land // since that means that we'll exit the process, emit the 'exit' event. try { if (!process._exiting) { @@ -586,7 +587,7 @@ function setupProcessFatal() { // Nothing to be done about it at this point. } try { - const { kExpandStackSymbol } = NativeModule.require('internal/util'); + const { kExpandStackSymbol } = internalUtil; if (typeof er[kExpandStackSymbol] === 'function') er[kExpandStackSymbol](); } catch { @@ -614,15 +615,13 @@ function setupProcessFatal() { } function setupProcessICUVersions() { - const icu = internalBinding('config').hasIntl ? - internalBinding('icu') : undefined; - if (!icu) return; // no Intl/ICU: nothing to add here. + if (!configBinding.hasIntl) return; // No Intl/ICU: nothing to add here. + const icu = internalBinding('icu'); // With no argument, getVersion() returns a comma separated list // of possible types. const versionTypes = icu.getVersion().split(','); - for (var n = 0; n < versionTypes.length; n++) { - const name = versionTypes[n]; + for (const name of versionTypes) { const version = icu.getVersion(name); Object.defineProperty(process.versions, name, { writable: false, @@ -642,20 +641,22 @@ function wrapForBreakOnFirstLine(source) { function evalScript(name, body) { const CJSModule = NativeModule.require('internal/modules/cjs/loader'); const path = NativeModule.require('path'); - const { tryGetCwd } = NativeModule.require('internal/util'); - const cwd = tryGetCwd(path); + const cwd = internalUtil.tryGetCwd(path); const module = new CJSModule(name); module.filename = path.join(cwd, name); module.paths = CJSModule._nodeModulePaths(cwd); - const script = `global.__filename = ${JSON.stringify(name)};\n` + - 'global.exports = exports;\n' + - 'global.module = module;\n' + - 'global.__dirname = __dirname;\n' + - 'global.require = require;\n' + - 'return require("vm").runInThisContext(' + - `${JSON.stringify(body)}, { filename: ` + - `${JSON.stringify(name)}, displayErrors: true });\n`; + const script = ` + global.__filename = ${JSON.stringify(name)}; + global.exports = exports; + global.module = module; + global.__dirname = __dirname; + global.require = require; + return require('vm').runInThisContext( + ${JSON.stringify(body)}, + { filename: ${JSON.stringify(name)}, displayErrors: true } + ); + `; const result = module._compile(script, `${name}-wrapper`); if (process._print_eval) console.log(result); // Handle any nextTicks added in the first tick of the program.