diff --git a/lib/internal/bootstrap/browser.js b/lib/internal/bootstrap/browser.js index 705ddc49dd8ade..b94ac9891a399c 100644 --- a/lib/internal/bootstrap/browser.js +++ b/lib/internal/bootstrap/browser.js @@ -42,9 +42,11 @@ defineOperation(globalThis, 'setTimeout', timers.setTimeout); exposeLazyInterfaces(globalThis, 'internal/abort_controller', [ 'AbortController', 'AbortSignal', ]); -exposeLazyInterfaces(globalThis, 'internal/event_target', [ - 'EventTarget', 'Event', -]); +const { + EventTarget, Event, +} = require('internal/event_target'); +exposeInterface(globalThis, 'Event', Event); +exposeInterface(globalThis, 'EventTarget', EventTarget); exposeLazyInterfaces(globalThis, 'internal/worker/io', [ 'MessageChannel', 'MessagePort', 'MessageEvent', ]); diff --git a/lib/internal/bootstrap/switches/is_main_thread.js b/lib/internal/bootstrap/switches/is_main_thread.js index 241729de35cf41..9ba3da2c90e085 100644 --- a/lib/internal/bootstrap/switches/is_main_thread.js +++ b/lib/internal/bootstrap/switches/is_main_thread.js @@ -286,3 +286,32 @@ rawMethods.resetStdioForTesting = function() { stdout = undefined; stderr = undefined; }; + +// Needed by the module loader and generally needed everywhere. +require('fs'); +require('util'); +require('url'); + +require('internal/modules/cjs/loader'); +require('internal/modules/esm/utils'); +require('internal/vm/module'); +// Needed to refresh the time origin. +require('internal/perf/utils'); +// Needed to register the async hooks. +if (internalBinding('config').hasInspector) { + require('internal/inspector_async_hook'); +} +// Needed to set the wasm web API callbacks. +internalBinding('wasm_web_api'); +// Needed to detect whether it's on main thread. +internalBinding('worker'); +// Needed to setup source maps. +require('internal/source_map/source_map_cache'); +// Needed by most execution modes. +require('internal/modules/run_main'); +// Needed to refresh DNS configurations. +require('internal/dns/utils'); +// Needed by almost all execution modes. It's fine to +// load them into the snapshot as long as we don't run +// any of the initialization. +require('internal/process/pre_execution'); diff --git a/lib/internal/main/eval_string.js b/lib/internal/main/eval_string.js index e92e088b8e0ceb..e8ecf9f1dae9cf 100644 --- a/lib/internal/main/eval_string.js +++ b/lib/internal/main/eval_string.js @@ -14,7 +14,7 @@ const { markBootstrapComplete } = require('internal/process/pre_execution'); const { evalModule, evalScript } = require('internal/process/execution'); -const { addBuiltinLibsToObject } = require('internal/modules/cjs/helpers'); +const { addBuiltinLibsToObject } = require('internal/modules/helpers'); const { getOptionValue } = require('internal/options'); diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 36efb48fc574cb..2e0be0e3d8a1f8 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -72,7 +72,8 @@ const cjsParseCache = new SafeWeakMap(); // Set first due to cycle with ESM loader functions. module.exports = { wrapSafe, Module, toRealPath, readPackageScope, cjsParseCache, - get hasLoadedAnyUserCJSModule() { return hasLoadedAnyUserCJSModule; } + get hasLoadedAnyUserCJSModule() { return hasLoadedAnyUserCJSModule; }, + initializeCJS, }; const { BuiltinModule } = require('internal/bootstrap/loaders'); @@ -86,8 +87,8 @@ const { kEmptyObject, filterOwnProperties, setOwnProperty, + getLazy, } = require('internal/util'); -const { Script } = require('vm'); const { internalCompileFunction } = require('internal/vm'); const assert = require('internal/assert'); const fs = require('fs'); @@ -97,21 +98,24 @@ const { sep } = path; const { internalModuleStat } = internalBinding('fs'); const { safeGetenv } = internalBinding('credentials'); const { - cjsConditions, + getCjsConditions, + initializeCjsConditions, hasEsmSyntax, loadBuiltinModule, makeRequireFunction, normalizeReferrerURL, stripBOM, -} = require('internal/modules/cjs/helpers'); -const { getOptionValue } = require('internal/options'); -const preserveSymlinks = getOptionValue('--preserve-symlinks'); -const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); -const shouldReportRequiredModules = process.env.WATCH_REPORT_DEPENDENCIES; -// Do not eagerly grab .manifest, it may be in TDZ -const policy = getOptionValue('--experimental-policy') ? - require('internal/process/policy') : - null; +} = require('internal/modules/helpers'); +const packageJsonReader = require('internal/modules/package_json_reader'); +const { getOptionValue, getEmbedderOptions } = require('internal/options'); +const policy = getLazy( + () => (getOptionValue('--experimental-policy') ? require('internal/process/policy') : null) +); +const shouldReportRequiredModules = getLazy(() => process.env.WATCH_REPORT_DEPENDENCIES); + +const getCascadedLoader = getLazy( + () => require('internal/process/esm_loader').esmLoader +); // Whether any user-provided CJS modules had been loaded (executed). // Used for internal assertions. @@ -127,7 +131,6 @@ const { setArrowMessage, } = require('internal/errors'); const { validateString } = require('internal/validators'); -const pendingDeprecation = getOptionValue('--pending-deprecation'); const { CHAR_BACKWARD_SLASH, @@ -140,15 +143,7 @@ const { isProxy } = require('internal/util/types'); -const asyncESM = require('internal/process/esm_loader'); -const { enrichCJSError } = require('internal/modules/esm/translators'); const { kEvaluated } = internalBinding('module_wrap'); -const { - encodedSepRegEx, - packageExportsResolve, - packageImportsResolve -} = require('internal/modules/esm/resolve'); - const isWindows = process.platform === 'win32'; const relativeResolveCache = ObjectCreate(null); @@ -190,13 +185,13 @@ function updateChildren(parent, child, scan) { } function reportModuleToWatchMode(filename) { - if (shouldReportRequiredModules && process.send) { + if (shouldReportRequiredModules() && process.send) { process.send({ 'watch:require': [filename] }); } } function reportModuleNotFoundToWatchMode(basePath, extensions) { - if (shouldReportRequiredModules && process.send) { + if (shouldReportRequiredModules() && process.send) { process.send({ 'watch:require': ArrayPrototypeMap(extensions, (ext) => path.resolve(`${basePath}${ext}`)) }); } } @@ -213,22 +208,6 @@ function Module(id = '', parent) { this.children = []; } -const builtinModules = []; -for (const { 0: id, 1: mod } of BuiltinModule.map) { - if (mod.canBeRequiredByUsers && - BuiltinModule.canBeRequiredWithoutScheme(id)) { - ArrayPrototypePush(builtinModules, id); - } -} - -const allBuiltins = new SafeSet( - ArrayPrototypeFlatMap(builtinModules, (bm) => [bm, `node:${bm}`]) -); -BuiltinModule.getSchemeOnlyModuleNames().forEach((builtin) => allBuiltins.add(`node:${builtin}`)); - -ObjectFreeze(builtinModules); -Module.builtinModules = builtinModules; - Module._cache = ObjectCreate(null); Module._pathCache = ObjectCreate(null); Module._extensions = ObjectCreate(null); @@ -297,26 +276,59 @@ function setModuleParent(value) { moduleParentCache.set(this, value); } -ObjectDefineProperty(Module.prototype, 'parent', { - __proto__: null, - get: pendingDeprecation ? deprecate( - getModuleParent, - 'module.parent is deprecated due to accuracy issues. Please use ' + - 'require.main to find program entry point instead.', - 'DEP0144' - ) : getModuleParent, - set: pendingDeprecation ? deprecate( - setModuleParent, - 'module.parent is deprecated due to accuracy issues. Please use ' + - 'require.main to find program entry point instead.', - 'DEP0144' - ) : setModuleParent, -}); - let debug = require('internal/util/debuglog').debuglog('module', (fn) => { debug = fn; }); -Module._debug = deprecate(debug, 'Module._debug is deprecated.', 'DEP0077'); + +const builtinModules = []; +// This function is called during pre-execution, before any user code is run. +function initializeCJS() { + const pendingDeprecation = getOptionValue('--pending-deprecation'); + ObjectDefineProperty(Module.prototype, 'parent', { + __proto__: null, + get: pendingDeprecation ? deprecate( + getModuleParent, + 'module.parent is deprecated due to accuracy issues. Please use ' + + 'require.main to find program entry point instead.', + 'DEP0144' + ) : getModuleParent, + set: pendingDeprecation ? deprecate( + setModuleParent, + 'module.parent is deprecated due to accuracy issues. Please use ' + + 'require.main to find program entry point instead.', + 'DEP0144' + ) : setModuleParent, + }); + Module._debug = deprecate(debug, 'Module._debug is deprecated.', 'DEP0077'); + + for (const { 0: id, 1: mod } of BuiltinModule.map) { + if (mod.canBeRequiredByUsers && + BuiltinModule.canBeRequiredWithoutScheme(id)) { + ArrayPrototypePush(builtinModules, id); + } + } + + const allBuiltins = new SafeSet( + ArrayPrototypeFlatMap(builtinModules, (bm) => [bm, `node:${bm}`]) + ); + BuiltinModule.getSchemeOnlyModuleNames().forEach((builtin) => allBuiltins.add(`node:${builtin}`)); + ObjectFreeze(builtinModules); + Module.builtinModules = builtinModules; + + Module.isBuiltin = function isBuiltin(moduleName) { + return allBuiltins.has(moduleName); + }; + + initializeCjsConditions(); + + if (!getEmbedderOptions().noGlobalSearchPaths) { + Module._initPaths(); + } + + // TODO(joyeecheung): deprecate this in favor of a proper hook? + Module.runMain = + require('internal/modules/run_main').executeUserEntryPoint; +} // Given a module name, and a list of paths to test, returns the first // matching file in the following precedence. @@ -337,7 +349,6 @@ function readPackage(requestPath) { const existing = packageJsonCache.get(jsonPath); if (existing !== undefined) return existing; - const packageJsonReader = require('internal/modules/package_json_reader'); const result = packageJsonReader.read(jsonPath); const json = result.containsKeys === false ? '{}' : result.string; if (json === undefined) { @@ -440,7 +451,7 @@ const realpathCache = new SafeMap(); function tryFile(requestPath, isMain) { const rc = _stat(requestPath); if (rc !== 0) return; - if (preserveSymlinks && !isMain) { + if (getOptionValue('--preserve-symlinks') && !isMain) { return path.resolve(requestPath); } return toRealPath(requestPath); @@ -511,9 +522,10 @@ function trySelf(parentPath, request) { } try { + const { packageExportsResolve } = require('internal/modules/esm/resolve'); return finalizeEsmResolution(packageExportsResolve( pathToFileURL(pkgPath + '/package.json'), expansion, pkg, - pathToFileURL(parentPath), cjsConditions), parentPath, pkgPath); + pathToFileURL(parentPath), getCjsConditions()), parentPath, pkgPath); } catch (e) { if (e.code === 'ERR_MODULE_NOT_FOUND') throw createEsmNotFoundErr(request, pkgPath + '/package.json'); @@ -535,9 +547,10 @@ function resolveExports(nmPath, request) { const pkg = _readPackage(pkgPath); if (pkg?.exports != null) { try { + const { packageExportsResolve } = require('internal/modules/esm/resolve'); return finalizeEsmResolution(packageExportsResolve( pathToFileURL(pkgPath + '/package.json'), '.' + expansion, pkg, null, - cjsConditions), null, pkgPath); + getCjsConditions()), null, pkgPath); } catch (e) { if (e.code === 'ERR_MODULE_NOT_FOUND') throw createEsmNotFoundErr(request, pkgPath + '/package.json'); @@ -616,19 +629,19 @@ Module._findPath = function(request, paths, isMain) { if (!trailingSlash) { if (rc === 0) { // File. if (!isMain) { - if (preserveSymlinks) { + if (getOptionValue('--preserve-symlinks')) { filename = path.resolve(basePath); } else { filename = toRealPath(basePath); } - } else if (preserveSymlinksMain) { - // For the main module, we use the preserveSymlinksMain flag instead + } else if (getOptionValue('--preserve-symlinks-main')) { + // For the main module, we use the --preserve-symlinks-main flag instead // mainly for backward compatibility, as the preserveSymlinks flag // historically has not applied to the main module. Most likely this // was intended to keep .bin/ binaries working, as following those // symlinks is usually required for the imports in the corresponding // files to resolve; that said, in some use cases following symlinks - // causes bigger problems which is why the preserveSymlinksMain option + // causes bigger problems which is why the --preserve-symlinks-main option // is needed. filename = path.resolve(basePath); } else { @@ -999,9 +1012,10 @@ Module._resolveFilename = function(request, parent, isMain, options) { const pkg = readPackageScope(parentPath) || {}; if (pkg.data?.imports != null) { try { + const { packageImportsResolve } = require('internal/modules/esm/resolve'); return finalizeEsmResolution( packageImportsResolve(request, pathToFileURL(parentPath), - cjsConditions), parentPath, + getCjsConditions()), parentPath, pkg.path); } catch (e) { if (e.code === 'ERR_MODULE_NOT_FOUND') @@ -1043,6 +1057,7 @@ Module._resolveFilename = function(request, parent, isMain, options) { }; function finalizeEsmResolution(resolved, parentPath, pkgPath) { + const { encodedSepRegEx } = require('internal/modules/esm/resolve'); if (RegExpPrototypeExec(encodedSepRegEx, resolved) !== null) throw new ERR_INVALID_MODULE_SPECIFIER( resolved, 'must not include encoded "/" or "\\" characters', parentPath); @@ -1081,14 +1096,14 @@ Module.prototype.load = function(filename) { Module._extensions[extension](this, filename); this.loaded = true; - const esmLoader = asyncESM.esmLoader; + const cascadedLoader = getCascadedLoader(); // Create module entry at load time to snapshot exports correctly const exports = this.exports; // Preemptively cache if ((module?.module === undefined || module.module.getStatus() < kEvaluated) && - !esmLoader.cjsCache.has(this)) - esmLoader.cjsCache.set(this, exports); + !cascadedLoader.cjsCache.has(this)) + cascadedLoader.cjsCache.set(this, exports); }; @@ -1113,17 +1128,20 @@ Module.prototype.require = function(id) { // (needed for setting breakpoint when called with --inspect-brk) let resolvedArgv; let hasPausedEntry = false; - +let Script; function wrapSafe(filename, content, cjsModuleInstance) { if (patched) { const wrapper = Module.wrap(content); + if (Script === undefined) { + ({ Script } = require('vm')); + } const script = new Script(wrapper, { filename, lineOffset: 0, importModuleDynamically: async (specifier, _, importAssertions) => { - const loader = asyncESM.esmLoader; - return loader.import(specifier, normalizeReferrerURL(filename), - importAssertions); + const cascadedLoader = getCascadedLoader(); + return cascadedLoader.import(specifier, normalizeReferrerURL(filename), + importAssertions); }, }); @@ -1147,9 +1165,9 @@ function wrapSafe(filename, content, cjsModuleInstance) { ], { filename, importModuleDynamically(specifier, _, importAssertions) { - const loader = asyncESM.esmLoader; - return loader.import(specifier, normalizeReferrerURL(filename), - importAssertions); + const cascadedLoader = getCascadedLoader(); + return cascadedLoader.import(specifier, normalizeReferrerURL(filename), + importAssertions); }, }); @@ -1160,8 +1178,10 @@ function wrapSafe(filename, content, cjsModuleInstance) { return result.function; } catch (err) { - if (process.mainModule === cjsModuleInstance) + if (process.mainModule === cjsModuleInstance) { + const { enrichCJSError } = require('internal/modules/esm/translators'); enrichCJSError(err, content); + } throw err; } } @@ -1173,10 +1193,11 @@ function wrapSafe(filename, content, cjsModuleInstance) { Module.prototype._compile = function(content, filename) { let moduleURL; let redirects; - if (policy?.manifest) { + const manifest = policy()?.manifest; + if (manifest) { moduleURL = pathToFileURL(filename); - redirects = policy.manifest.getDependencyMapper(moduleURL); - policy.manifest.assertIntegrity(moduleURL, content); + redirects = manifest.getDependencyMapper(moduleURL); + manifest.assertIntegrity(moduleURL, content); } const compiledWrapper = wrapSafe(filename, content, this); @@ -1277,9 +1298,10 @@ Module._extensions['.js'] = function(module, filename) { Module._extensions['.json'] = function(module, filename) { const content = fs.readFileSync(filename, 'utf8'); - if (policy?.manifest) { + const manifest = policy()?.manifest; + if (manifest) { const moduleURL = pathToFileURL(filename); - policy.manifest.assertIntegrity(moduleURL, content); + manifest.assertIntegrity(moduleURL, content); } try { @@ -1293,10 +1315,11 @@ Module._extensions['.json'] = function(module, filename) { // Native extension for .node Module._extensions['.node'] = function(module, filename) { - if (policy?.manifest) { + const manifest = policy()?.manifest; + if (manifest) { const content = fs.readFileSync(filename); const moduleURL = pathToFileURL(filename); - policy.manifest.assertIntegrity(moduleURL, content); + manifest.assertIntegrity(moduleURL, content); } // Be aware this doesn't use `content` return process.dlopen(module, path.toNamespacedPath(filename)); @@ -1405,9 +1428,5 @@ Module.syncBuiltinESMExports = function syncBuiltinESMExports() { } }; -Module.isBuiltin = function isBuiltin(moduleName) { - return allBuiltins.has(moduleName); -}; - // Backwards compatibility Module.Module = Module; diff --git a/lib/internal/modules/esm/create_dynamic_module.js b/lib/internal/modules/esm/create_dynamic_module.js index f7c20083b6c918..1abb909f58526b 100644 --- a/lib/internal/modules/esm/create_dynamic_module.js +++ b/lib/internal/modules/esm/create_dynamic_module.js @@ -35,7 +35,7 @@ ${ArrayPrototypeJoin(ArrayPrototypeMap(imports, createImport), '\n')} ${ArrayPrototypeJoin(ArrayPrototypeMap(exports, createExport), '\n')} import.meta.done(); `; - const { ModuleWrap, callbackMap } = internalBinding('module_wrap'); + const { ModuleWrap } = internalBinding('module_wrap'); const m = new ModuleWrap(`${url}`, undefined, source, 0, 0); const readyfns = new SafeSet(); @@ -46,8 +46,8 @@ import.meta.done(); if (imports.length) reflect.imports = ObjectCreate(null); - - callbackMap.set(m, { + const { setCallbackForWrap } = require('internal/modules/esm/utils'); + setCallbackForWrap(m, { initializeImportMeta: (meta, wrap) => { meta.exports = reflect.exports; if (reflect.imports) diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index c30cc13756cdf4..9a422e8f70f1ce 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -47,9 +47,12 @@ function newModuleMap() { const { defaultResolve, - DEFAULT_CONDITIONS, } = require('internal/modules/esm/resolve'); +const { + getDefaultConditions, +} = require('internal/modules/esm/utils'); + function getTranslators() { const { translators } = require('internal/modules/esm/translators'); return translators; @@ -363,9 +366,10 @@ class ESMLoader { url = pathToFileURL(`${process.cwd()}/[eval${++this.evalIndex}]`).href ) { const evalInstance = (url) => { - const { ModuleWrap, callbackMap } = internalBinding('module_wrap'); + const { ModuleWrap } = internalBinding('module_wrap'); + const { setCallbackForWrap } = require('internal/modules/esm/utils'); const module = new ModuleWrap(url, undefined, source, 0, 0); - callbackMap.set(module, { + setCallbackForWrap(module, { importModuleDynamically: (specifier, { url }, importAssertions) => { return this.import(specifier, url, importAssertions); } @@ -798,7 +802,7 @@ class ESMLoader { } const chain = this.#hooks.resolve; const context = { - conditions: DEFAULT_CONDITIONS, + conditions: getDefaultConditions(), importAssertions, parentURL, }; diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index e4ad685a6938e7..aa979eec36fe8b 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -6,7 +6,6 @@ const { ArrayPrototypeJoin, ArrayPrototypeShift, JSONStringify, - ObjectFreeze, ObjectGetOwnPropertyNames, ObjectPrototypeHasOwnProperty, RegExp, @@ -45,7 +44,6 @@ const typeFlag = getOptionValue('--input-type'); const { URL, pathToFileURL, fileURLToPath } = require('internal/url'); const { ERR_INPUT_TYPE_NOT_ALLOWED, - ERR_INVALID_ARG_VALUE, ERR_INVALID_MODULE_SPECIFIER, ERR_INVALID_PACKAGE_CONFIG, ERR_INVALID_PACKAGE_TARGET, @@ -60,25 +58,13 @@ const { const { Module: CJSModule } = require('internal/modules/cjs/loader'); const { getPackageConfig, getPackageScopeConfig } = require('internal/modules/esm/package_config'); +const { getConditionsSet } = require('internal/modules/esm/utils'); /** * @typedef {import('internal/modules/esm/package_config.js').PackageConfig} PackageConfig */ -const userConditions = getOptionValue('--conditions'); -const noAddons = getOptionValue('--no-addons'); -const addonConditions = noAddons ? [] : ['node-addons']; - -const DEFAULT_CONDITIONS = ObjectFreeze([ - 'node', - 'import', - ...addonConditions, - ...userConditions, -]); - -const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS); - const emittedPackageWarnings = new SafeSet(); function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) { @@ -147,21 +133,6 @@ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) { ); } -/** - * @param {string[]} [conditions] - * @returns {Set} - */ -function getConditionsSet(conditions) { - if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) { - if (!ArrayIsArray(conditions)) { - throw new ERR_INVALID_ARG_VALUE('conditions', conditions, - 'expected an array'); - } - return new SafeSet(conditions); - } - return DEFAULT_CONDITIONS_SET; -} - const realpathCache = new SafeMap(); /** @@ -1125,7 +1096,6 @@ async function defaultResolve(specifier, context = {}) { } module.exports = { - DEFAULT_CONDITIONS, defaultResolve, encodedSepRegEx, getPackageScopeConfig, diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 38fa41e47603dd..b21c3c18cf7383 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -30,7 +30,7 @@ const { hasEsmSyntax, loadBuiltinModule, stripBOM, -} = require('internal/modules/cjs/helpers'); +} = require('internal/modules/helpers'); const { Module: CJSModule, cjsParseCache @@ -115,7 +115,8 @@ translators.set('module', async function moduleStrategy(url, source, isMain) { maybeCacheSourceMap(url, source); debug(`Translating StandardModule ${url}`); const module = new ModuleWrap(url, undefined, source, 0, 0); - moduleWrap.callbackMap.set(module, { + const { setCallbackForWrap } = require('internal/modules/esm/utils'); + setCallbackForWrap(module, { initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }), importModuleDynamically, }); diff --git a/lib/internal/modules/esm/utils.js b/lib/internal/modules/esm/utils.js new file mode 100644 index 00000000000000..2927326097a152 --- /dev/null +++ b/lib/internal/modules/esm/utils.js @@ -0,0 +1,105 @@ +'use strict'; +const { + ArrayIsArray, + SafeSet, + SafeWeakMap, + ObjectFreeze, +} = primordials; + +const { + ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, + ERR_INVALID_ARG_VALUE, +} = require('internal/errors').codes; + +const { getOptionValue } = require('internal/options'); + +const { + setImportModuleDynamicallyCallback, + setInitializeImportMetaObjectCallback +} = internalBinding('module_wrap'); +const { + getModuleFromWrap, +} = require('internal/vm/module'); +const assert = require('internal/assert'); + +const callbackMap = new SafeWeakMap(); +function setCallbackForWrap(wrap, data) { + callbackMap.set(wrap, data); +} + +let defaultConditions; +function getDefaultConditions() { + assert(defaultConditions !== undefined); + return defaultConditions; +} + +let defaultConditionsSet; +function getDefaultConditionsSet() { + assert(defaultConditionsSet !== undefined); + return defaultConditionsSet; +} + +// This function is called during pre-execution, before any user code is run. +function initializeDefaultConditions() { + const userConditions = getOptionValue('--conditions'); + const noAddons = getOptionValue('--no-addons'); + const addonConditions = noAddons ? [] : ['node-addons']; + + defaultConditions = ObjectFreeze([ + 'node', + 'import', + ...addonConditions, + ...userConditions, + ]); + defaultConditionsSet = new SafeSet(defaultConditions); +} + +/** + * @param {string[]} [conditions] + * @returns {Set} + */ +function getConditionsSet(conditions) { + if (conditions !== undefined && conditions !== getDefaultConditions()) { + if (!ArrayIsArray(conditions)) { + throw new ERR_INVALID_ARG_VALUE('conditions', conditions, + 'expected an array'); + } + return new SafeSet(conditions); + } + return getDefaultConditionsSet(); +} + +function initializeImportMetaObject(wrap, meta) { + if (callbackMap.has(wrap)) { + const { initializeImportMeta } = callbackMap.get(wrap); + if (initializeImportMeta !== undefined) { + initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap); + } + } +} + +async function importModuleDynamicallyCallback(wrap, specifier, assertions) { + if (callbackMap.has(wrap)) { + const { importModuleDynamically } = callbackMap.get(wrap); + if (importModuleDynamically !== undefined) { + return importModuleDynamically( + specifier, getModuleFromWrap(wrap) || wrap, assertions); + } + } + throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING(); +} + +function initializeESM() { + initializeDefaultConditions(); + // Setup per-isolate callbacks that locate data or callbacks that we keep + // track of for different ESM modules. + setInitializeImportMetaObjectCallback(initializeImportMetaObject); + setImportModuleDynamicallyCallback(importModuleDynamicallyCallback); +} + +module.exports = { + setCallbackForWrap, + initializeESM, + getDefaultConditions, + getConditionsSet, +}; diff --git a/lib/internal/modules/cjs/helpers.js b/lib/internal/modules/helpers.js similarity index 91% rename from lib/internal/modules/cjs/helpers.js rename to lib/internal/modules/helpers.js index fea3fbcf48dc00..49c086279e238d 100644 --- a/lib/internal/modules/cjs/helpers.js +++ b/lib/internal/modules/helpers.js @@ -25,22 +25,31 @@ const { pathToFileURL, fileURLToPath, URL } = require('internal/url'); const { getOptionValue } = require('internal/options'); const { setOwnProperty } = require('internal/util'); -const userConditions = getOptionValue('--conditions'); let debug = require('internal/util/debuglog').debuglog('module', (fn) => { debug = fn; }); -const noAddons = getOptionValue('--no-addons'); -const addonConditions = noAddons ? [] : ['node-addons']; +let cjsConditions; +function initializeCjsConditions() { + const userConditions = getOptionValue('--conditions'); + const noAddons = getOptionValue('--no-addons'); + const addonConditions = noAddons ? [] : ['node-addons']; + // TODO: Use this set when resolving pkg#exports conditions in loader.js. + cjsConditions = new SafeSet([ + 'require', + 'node', + ...addonConditions, + ...userConditions, + ]); +} -// TODO: Use this set when resolving pkg#exports conditions in loader.js. -const cjsConditions = new SafeSet([ - 'require', - 'node', - ...addonConditions, - ...userConditions, -]); +function getCjsConditions() { + if (cjsConditions === undefined) { + initializeCjsConditions(); + } + return cjsConditions; +} function loadBuiltinModule(filename, request) { const mod = BuiltinModule.map.get(filename); @@ -62,7 +71,7 @@ function makeRequireFunction(mod, redirects) { let require; if (redirects) { const id = mod.filename || mod.id; - const conditions = cjsConditions; + const conditions = getCjsConditions(); const { resolve, reaction } = redirects; require = function require(specifier) { let missing = true; @@ -231,7 +240,8 @@ function hasEsmSyntax(code) { module.exports = { addBuiltinLibsToObject, - cjsConditions, + getCjsConditions, + initializeCjsConditions, hasEsmSyntax, loadBuiltinModule, makeRequireFunction, diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js index 738c945bc21c21..c948eaf4ae4437 100644 --- a/lib/internal/modules/run_main.js +++ b/lib/internal/modules/run_main.js @@ -4,8 +4,7 @@ const { ObjectCreate, StringPrototypeEndsWith, } = primordials; -const CJSLoader = require('internal/modules/cjs/loader'); -const { Module, toRealPath, readPackageScope } = CJSLoader; + const { getOptionValue } = require('internal/options'); const path = require('path'); @@ -13,6 +12,7 @@ function resolveMainPath(main) { // Note extension resolution for the main entry point can be deprecated in a // future major. // Module._findPath is monkey-patchable here. + const { Module, toRealPath } = require('internal/modules/cjs/loader'); let mainPath = Module._findPath(path.resolve(main), null, true); if (!mainPath) return; @@ -37,6 +37,7 @@ function shouldUseESMLoader(mainPath) { const userImports = getOptionValue('--import'); if (userLoaders.length > 0 || userImports.length > 0) return true; + const { readPackageScope } = require('internal/modules/cjs/loader'); // Determine the module format of the main if (mainPath && StringPrototypeEndsWith(mainPath, '.mjs')) return true; @@ -79,6 +80,7 @@ function executeUserEntryPoint(main = process.argv[1]) { runMainESM(resolvedMain || main); } else { // Module._load is the monkey-patchable CJS module loader. + const { Module } = require('internal/modules/cjs/loader'); Module._load(main, null, true); } } diff --git a/lib/internal/process/esm_loader.js b/lib/internal/process/esm_loader.js index 473cea48cafe64..25a2b7191cb5d4 100644 --- a/lib/internal/process/esm_loader.js +++ b/lib/internal/process/esm_loader.js @@ -5,40 +5,11 @@ const { ObjectCreate, } = primordials; -const { - ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, -} = require('internal/errors').codes; const { ESMLoader } = require('internal/modules/esm/loader'); const { hasUncaughtExceptionCaptureCallback, } = require('internal/process/execution'); const { pathToFileURL } = require('internal/url'); -const { - getModuleFromWrap, -} = require('internal/vm/module'); - -exports.initializeImportMetaObject = function(wrap, meta) { - const { callbackMap } = internalBinding('module_wrap'); - if (callbackMap.has(wrap)) { - const { initializeImportMeta } = callbackMap.get(wrap); - if (initializeImportMeta !== undefined) { - initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap); - } - } -}; - -exports.importModuleDynamicallyCallback = -async function importModuleDynamicallyCallback(wrap, specifier, assertions) { - const { callbackMap } = internalBinding('module_wrap'); - if (callbackMap.has(wrap)) { - const { importModuleDynamically } = callbackMap.get(wrap); - if (importModuleDynamically !== undefined) { - return importModuleDynamically( - specifier, getModuleFromWrap(wrap) || wrap, assertions); - } - } - throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING(); -}; const esmLoader = new ESMLoader(); exports.esmLoader = esmLoader; diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js index d808f65424c2de..c3e84854ccefdd 100644 --- a/lib/internal/process/pre_execution.js +++ b/lib/internal/process/pre_execution.js @@ -6,14 +6,12 @@ const { ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, SafeMap, - SafeWeakMap, StringPrototypeStartsWith, globalThis, } = primordials; const { getOptionValue, - getEmbedderOptions, refreshOptions, } = require('internal/options'); const { reconnectZeroFillToggle } = require('internal/buffer'); @@ -82,6 +80,7 @@ function prepareExecution(options) { initializeSourceMapsHandlers(); initializeDeprecations(); initializeWASI(); + require('internal/dns/utils').initializeDns(); if (isMainThread) { @@ -264,8 +263,9 @@ function setupFetch() { }); // The WebAssembly Web API: https://webassembly.github.io/spec/web-api - const { wasmStreamingCallback } = require('internal/wasm_web_api'); - internalBinding('wasm_web_api').setImplementation(wasmStreamingCallback); + internalBinding('wasm_web_api').setImplementation((streamState, source) => { + require('internal/wasm_web_api').wasmStreamingCallback(streamState, source); + }); } // TODO(aduh95): move this to internal/bootstrap/browser when the CLI flag is @@ -338,12 +338,12 @@ function setupStacktracePrinterOnSigint() { } function initializeReport() { - const { report } = require('internal/process/report'); ObjectDefineProperty(process, 'report', { __proto__: null, enumerable: true, configurable: true, get() { + const { report } = require('internal/process/report'); return report; } }); @@ -358,9 +358,10 @@ function setupDebugEnv() { // This has to be called after initializeReport() is called function initializeReportSignalHandlers() { - const { addSignalHandler } = require('internal/process/report'); - - addSignalHandler(); + if (getOptionValue('--report-on-signal')) { + const { addSignalHandler } = require('internal/process/report'); + addSignalHandler(); + } } function initializeHeapSnapshotSignalHandlers() { @@ -561,30 +562,13 @@ function initializeWASI() { } function initializeCJSLoader() { - const CJSLoader = require('internal/modules/cjs/loader'); - if (!getEmbedderOptions().noGlobalSearchPaths) { - CJSLoader.Module._initPaths(); - } - // TODO(joyeecheung): deprecate this in favor of a proper hook? - CJSLoader.Module.runMain = - require('internal/modules/run_main').executeUserEntryPoint; + const { initializeCJS } = require('internal/modules/cjs/loader'); + initializeCJS(); } function initializeESMLoader() { - // Create this WeakMap in js-land because V8 has no C++ API for WeakMap. - internalBinding('module_wrap').callbackMap = new SafeWeakMap(); - - if (getEmbedderOptions().shouldNotRegisterESMLoader) return; - - const { - setImportModuleDynamicallyCallback, - setInitializeImportMetaObjectCallback - } = internalBinding('module_wrap'); - const esm = require('internal/process/esm_loader'); - // Setup per-isolate callbacks that locate data or callbacks that we keep - // track of for different ESM modules. - setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject); - setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback); + const { initializeESM } = require('internal/modules/esm/utils'); + initializeESM(); // Patch the vm module when --experimental-vm-modules is on. // Please update the comments in vm.js when this block changes. diff --git a/lib/internal/source_map/source_map_cache.js b/lib/internal/source_map/source_map_cache.js index 1eb5c69bd3ff93..2faf4489059b1e 100644 --- a/lib/internal/source_map/source_map_cache.js +++ b/lib/internal/source_map/source_map_cache.js @@ -24,17 +24,19 @@ let debug = require('internal/util/debuglog').debuglog('source_map', (fn) => { debug = fn; }); const { getOptionValue } = require('internal/options'); -const { IterableWeakMap } = require('internal/util/iterable_weak_map'); -const { - normalizeReferrerURL, -} = require('internal/modules/cjs/helpers'); + const { validateBoolean } = require('internal/validators'); const { setMaybeCacheGeneratedSourceMap } = internalBinding('errors'); +const { getLazy } = require('internal/util'); // Since the CJS module cache is mutable, which leads to memory leaks when // modules are deleted, we use a WeakMap so that the source map cache will // be purged automatically: -const cjsSourceMapCache = new IterableWeakMap(); +const getCjsSourceMapCache = getLazy(() => { + const { IterableWeakMap } = require('internal/util/iterable_weak_map'); + return new IterableWeakMap(); +}); + // The esm cache is not mutable, so we can use a Map without memory concerns: const esmSourceMapCache = new SafeMap(); // The generated sources is not mutable, so we can use a Map without memory concerns: @@ -44,6 +46,7 @@ const kSourceMappingURLMagicComment = /\/[*/]#\s+sourceMappingURL=(?[^\s]+)/g; const { fileURLToPath, pathToFileURL, URL } = require('internal/url'); + let SourceMap; let sourceMapsEnabled; @@ -114,6 +117,7 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance, isGeneratedSo const sourceMapsEnabled = getSourceMapsEnabled(); if (!(process.env.NODE_V8_COVERAGE || sourceMapsEnabled)) return; try { + const { normalizeReferrerURL } = require('internal/modules/helpers'); filename = normalizeReferrerURL(filename); } catch (err) { // This is most likely an invalid filename in sourceURL of [eval]-wrapper. @@ -137,7 +141,7 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance, isGeneratedSo const data = dataFromUrl(filename, sourceMapURL); const url = data ? null : sourceMapURL; if (cjsModuleInstance) { - cjsSourceMapCache.set(cjsModuleInstance, { + getCjsSourceMapCache().set(cjsModuleInstance, { filename, lineLengths: lineLengths(content), data, @@ -291,7 +295,7 @@ function sourceMapCacheToObject() { } function appendCJSCache(obj) { - for (const value of cjsSourceMapCache) { + for (const value of getCjsSourceMapCache()) { obj[ObjectGetValueSafe(value, 'filename')] = { lineLengths: ObjectGetValueSafe(value, 'lineLengths'), data: ObjectGetValueSafe(value, 'data'), @@ -309,7 +313,7 @@ function findSourceMap(sourceURL) { } let sourceMap = esmSourceMapCache.get(sourceURL) ?? generatedSourceMapCache.get(sourceURL); if (sourceMap === undefined) { - for (const value of cjsSourceMapCache) { + for (const value of getCjsSourceMapCache()) { const filename = ObjectGetValueSafe(value, 'filename'); const cachedSourceURL = ObjectGetValueSafe(value, 'sourceURL'); if (sourceURL === filename || sourceURL === cachedSourceURL) { diff --git a/lib/internal/util.js b/lib/internal/util.js index fd4a6e3eca3421..245fcbc0d0b927 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -654,7 +654,26 @@ function isArrayBufferDetached(value) { return false; } +/** + * Helper function to lazy-load an initialize-once value. + * @template T Return value of initializer + * @param {()=>T} initializer Initializer of the lazily loaded value. + * @returns {()=>T} + */ +function getLazy(initializer) { + let value; + let initialized = false; + return function() { + if (initialized === false) { + value = initializer(); + initialized = true; + } + return value; + }; +} + module.exports = { + getLazy, assertCrypto, cachedResult, convertToValidSignal, diff --git a/lib/internal/util/inspector.js b/lib/internal/util/inspector.js index c7f18ffdb61a33..3a589423b2d280 100644 --- a/lib/internal/util/inspector.js +++ b/lib/internal/util/inspector.js @@ -66,7 +66,7 @@ function installConsoleExtensions(commandLineApi) { if (commandLineApi.require) { return; } const { tryGetCwd } = require('internal/process/execution'); const CJSModule = require('internal/modules/cjs/loader').Module; - const { makeRequireFunction } = require('internal/modules/cjs/helpers'); + const { makeRequireFunction } = require('internal/modules/helpers'); const consoleAPIModule = new CJSModule(''); const cwd = tryGetCwd(); consoleAPIModule.paths = ArrayPrototypeConcat( diff --git a/lib/internal/vm.js b/lib/internal/vm.js index 32bcdf06234b67..a813c55d9e3aad 100644 --- a/lib/internal/vm.js +++ b/lib/internal/vm.js @@ -94,12 +94,11 @@ function internalCompileFunction(code, params, options) { if (importModuleDynamically !== undefined) { validateFunction(importModuleDynamically, 'options.importModuleDynamically'); - const { importModuleDynamicallyWrap } = - require('internal/vm/module'); - const { callbackMap } = internalBinding('module_wrap'); + const { importModuleDynamicallyWrap } = require('internal/vm/module'); const wrapped = importModuleDynamicallyWrap(importModuleDynamically); const func = result.function; - callbackMap.set(result.cacheKey, { + const { setCallbackForWrap } = require('internal/modules/esm/utils'); + setCallbackForWrap(result.cacheKey, { importModuleDynamically: (s, _k, i) => wrapped(s, func, i), }); } diff --git a/lib/internal/vm/module.js b/lib/internal/vm/module.js index 7e0131c7db2872..91d489fc4c7cdd 100644 --- a/lib/internal/vm/module.js +++ b/lib/internal/vm/module.js @@ -125,8 +125,8 @@ class Module { this[kWrap] = new ModuleWrap(identifier, context, sourceText, options.lineOffset, options.columnOffset, options.cachedData); - - binding.callbackMap.set(this[kWrap], { + const { setCallbackForWrap } = require('internal/modules/esm/utils'); + setCallbackForWrap(this[kWrap], { initializeImportMeta: options.initializeImportMeta, importModuleDynamically: options.importModuleDynamically ? importModuleDynamicallyWrap(options.importModuleDynamically) : diff --git a/lib/repl.js b/lib/repl.js index 0780b5a54743c6..60e454e5374960 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -103,7 +103,7 @@ const { BuiltinModule } = require('internal/bootstrap/loaders'); const { makeRequireFunction, addBuiltinLibsToObject -} = require('internal/modules/cjs/helpers'); +} = require('internal/modules/helpers'); const { isIdentifierStart, isIdentifierChar diff --git a/lib/vm.js b/lib/vm.js index ec91c8a2651775..dea012156628b6 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -111,10 +111,9 @@ class Script extends ContextifyScript { if (importModuleDynamically !== undefined) { validateFunction(importModuleDynamically, 'options.importModuleDynamically'); - const { importModuleDynamicallyWrap } = - require('internal/vm/module'); - const { callbackMap } = internalBinding('module_wrap'); - callbackMap.set(this, { + const { importModuleDynamicallyWrap } = require('internal/vm/module'); + const { setCallbackForWrap } = require('internal/modules/esm/utils'); + setCallbackForWrap(this, { importModuleDynamically: importModuleDynamicallyWrap(importModuleDynamically), }); diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 73ce4aa42035a1..d6c766244fd416 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -4,6 +4,7 @@ #include "memory_tracker-inl.h" #include "node_contextify.h" #include "node_errors.h" +#include "node_external_reference.h" #include "node_internals.h" #include "node_process-inl.h" #include "node_url.h" @@ -811,8 +812,27 @@ void ModuleWrap::Initialize(Local target, #undef V } +void ModuleWrap::RegisterExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(New); + + registry->Register(Link); + registry->Register(Instantiate); + registry->Register(Evaluate); + registry->Register(SetSyntheticExport); + registry->Register(CreateCachedData); + registry->Register(GetNamespace); + registry->Register(GetStatus); + registry->Register(GetError); + registry->Register(GetStaticDependencySpecifiers); + + registry->Register(SetImportModuleDynamicallyCallback); + registry->Register(SetInitializeImportMetaObjectCallback); +} } // namespace loader } // namespace node NODE_BINDING_CONTEXT_AWARE_INTERNAL(module_wrap, node::loader::ModuleWrap::Initialize) +NODE_BINDING_EXTERNAL_REFERENCE( + module_wrap, node::loader::ModuleWrap::RegisterExternalReferences) diff --git a/src/module_wrap.h b/src/module_wrap.h index 58b233d036515c..c609ba5509dcd0 100644 --- a/src/module_wrap.h +++ b/src/module_wrap.h @@ -11,6 +11,7 @@ namespace node { class Environment; +class ExternalReferenceRegistry; namespace contextify { class ContextifyContext; @@ -44,6 +45,7 @@ class ModuleWrap : public BaseObject { v8::Local unused, v8::Local context, void* priv); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); static void HostInitializeImportMetaObjectCallback( v8::Local context, v8::Local module, diff --git a/src/node_external_reference.h b/src/node_external_reference.h index bf4b49670de310..c3ab57c0bb0f98 100644 --- a/src/node_external_reference.h +++ b/src/node_external_reference.h @@ -74,6 +74,7 @@ class ExternalReferenceRegistry { V(heap_utils) \ V(messaging) \ V(mksnapshot) \ + V(module_wrap) \ V(options) \ V(os) \ V(performance) \ diff --git a/test/fixtures/inspector-global-function.js b/test/fixtures/inspector-global-function.mjs similarity index 100% rename from test/fixtures/inspector-global-function.js rename to test/fixtures/inspector-global-function.mjs diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js index d3111513424182..693fa9efb4111b 100644 --- a/test/parallel/test-bootstrap-modules.js +++ b/test/parallel/test-bootstrap-modules.js @@ -25,7 +25,6 @@ const expectedModules = new Set([ 'Internal Binding options', 'Internal Binding performance', 'Internal Binding process_methods', - 'Internal Binding report', 'Internal Binding string_decoder', 'Internal Binding symbols', 'Internal Binding task_queue', @@ -53,30 +52,19 @@ const expectedModules = new Set([ 'NativeModule internal/fs/utils', 'NativeModule internal/idna', 'NativeModule internal/linkedlist', - 'NativeModule internal/modules/cjs/helpers', 'NativeModule internal/modules/cjs/loader', - 'NativeModule internal/modules/esm/assert', - 'NativeModule internal/modules/esm/formats', - 'NativeModule internal/modules/esm/get_format', - 'NativeModule internal/modules/esm/initialize_import_meta', - 'NativeModule internal/modules/esm/load', - 'NativeModule internal/modules/esm/loader', - 'NativeModule internal/modules/esm/module_map', - 'NativeModule internal/modules/esm/package_config', - 'NativeModule internal/modules/esm/resolve', - 'NativeModule internal/modules/esm/translators', + 'NativeModule internal/modules/esm/utils', + 'NativeModule internal/modules/helpers', 'NativeModule internal/modules/package_json_reader', 'NativeModule internal/modules/run_main', 'NativeModule internal/net', 'NativeModule internal/options', 'NativeModule internal/perf/utils', 'NativeModule internal/priority_queue', - 'NativeModule internal/process/esm_loader', 'NativeModule internal/process/execution', 'NativeModule internal/process/per_thread', 'NativeModule internal/process/pre_execution', 'NativeModule internal/process/promises', - 'NativeModule internal/process/report', 'NativeModule internal/process/signal', 'NativeModule internal/process/task_queues', 'NativeModule internal/process/warning', @@ -87,28 +75,21 @@ const expectedModules = new Set([ 'NativeModule internal/util', 'NativeModule internal/util/debuglog', 'NativeModule internal/util/inspect', - 'NativeModule internal/util/iterable_weak_map', 'NativeModule internal/util/types', 'NativeModule internal/v8/startup_snapshot', 'NativeModule internal/validators', 'NativeModule internal/vm', 'NativeModule internal/vm/module', - 'NativeModule internal/wasm_web_api', 'NativeModule internal/worker/js_transferable', 'NativeModule path', 'NativeModule querystring', 'NativeModule timers', 'NativeModule url', 'NativeModule util', - 'NativeModule vm', ]); if (!common.isMainThread) { [ - 'Internal Binding messaging', - 'Internal Binding performance', - 'Internal Binding symbols', - 'Internal Binding worker', 'NativeModule diagnostics_channel', 'NativeModule internal/abort_controller', 'NativeModule internal/error_serdes', @@ -139,6 +120,11 @@ if (!common.isMainThread) { ].forEach(expectedModules.add.bind(expectedModules)); } +if (common.isWindows) { + // On Windows fs needs SideEffectFreeRegExpPrototypeExec which uses vm. + expectedModules.add('NativeModule vm'); +} + if (common.hasIntl) { expectedModules.add('Internal Binding icu'); } else { diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 57f8dd064005c6..2e0d726d3dcecb 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -2832,7 +2832,7 @@ assert.strictEqual( ' at Function.Module._load (node:internal/modules/cjs/loader:621:3)', // This file is not an actual Node.js core file. ' at Module.require [as weird/name] (node:internal/aaaaa/loader:735:19)', - ' at require (node:internal/modules/cjs/helpers:14:16)', + ' at require (node:internal/modules/helpers:14:16)', ' at Array.forEach ()', ` at ${process.cwd()}/test/parallel/test-util-inspect.js:2760:12`, ` at Object. (${process.cwd()}/node_modules/hyper_module/folder/file.js:2753:10)`, diff --git a/test/sequential/test-inspector-break-when-eval.js b/test/sequential/test-inspector-break-when-eval.js index 1e7ab513dadbbb..bd9969e0dcfffd 100644 --- a/test/sequential/test-inspector-break-when-eval.js +++ b/test/sequential/test-inspector-break-when-eval.js @@ -6,7 +6,10 @@ const { NodeInstance } = require('../common/inspector-helper.js'); const fixtures = require('../common/fixtures'); const { pathToFileURL } = require('url'); -const script = fixtures.path('inspector-global-function.js'); +// This needs to be an ES module file to ensure that internal modules are +// loaded before pausing. See +// https://bugs.chromium.org/p/chromium/issues/detail?id=1246905 +const script = fixtures.path('inspector-global-function.mjs'); async function setupDebugger(session) { console.log('[test]', 'Setting up a debugger'); @@ -23,7 +26,7 @@ async function setupDebugger(session) { // NOTE(mmarchini): We wait for the second console.log to ensure we loaded // every internal module before pausing. See - // https://bugs.chromium.org/p/v8/issues/detail?id=10287. + // https://bugs.chromium.org/p/chromium/issues/detail?id=1246905 const waitForReady = session.waitForConsoleOutput('log', 'Ready!'); session.send({ 'method': 'Debugger.resume' }); await waitForReady;