diff --git a/lib/internal/modules/helpers.js b/lib/internal/modules/helpers.js index 307a34cb09b512..3c40df279e4187 100644 --- a/lib/internal/modules/helpers.js +++ b/lib/internal/modules/helpers.js @@ -37,7 +37,13 @@ let debug = require('internal/util/debuglog').debuglog('module', (fn) => { debug = fn; }); +/** @typedef {import('internal/modules/cjs/loader.js').Module} Module */ + +/** @type {Set} */ let cjsConditions; +/** + * Define the conditions that apply to the CommonJS loader. + */ function initializeCjsConditions() { const userConditions = getOptionValue('--conditions'); const noAddons = getOptionValue('--no-addons'); @@ -51,6 +57,9 @@ function initializeCjsConditions() { ]); } +/** + * Get the conditions that apply to the CommonJS loader. + */ function getCjsConditions() { if (cjsConditions === undefined) { initializeCjsConditions(); @@ -58,27 +67,44 @@ function getCjsConditions() { return cjsConditions; } -function loadBuiltinModule(filename, request) { - if (!BuiltinModule.canBeRequiredByUsers(filename)) { +/** + * Provide one of Node.js' public modules to user code. + * @param {string} id The identifier/specifier of the builtin module to load + * @param {string} request The module requiring or importing the builtin module + */ +function loadBuiltinModule(id, request) { + if (!BuiltinModule.canBeRequiredByUsers(id)) { return; } - const mod = BuiltinModule.map.get(filename); + /** @type {import('internal/bootstrap/realm.js').BuiltinModule} */ + const mod = BuiltinModule.map.get(id); debug('load built-in module %s', request); // compileForPublicLoader() throws if canBeRequiredByUsers is false: mod.compileForPublicLoader(); return mod; } +/** @type {Module} */ let $Module = null; +/** + * Import the Module class on first use. + */ function lazyModule() { $Module = $Module || require('internal/modules/cjs/loader').Module; return $Module; } -// Invoke with makeRequireFunction(module) where |module| is the Module object -// to use as the context for the require() function. -// Use redirects to set up a mapping from a policy and restrict dependencies +/** + * Invoke with `makeRequireFunction(module)` where `module` is the `Module` object to use as the context for the + * `require()` function. + * Use redirects to set up a mapping from a policy and restrict dependencies. + */ const urlToFileCache = new SafeMap(); +/** + * Create the module-scoped `require` function to pass into CommonJS modules. + * @param {Module} mod The module to create the `require` function for. + * @param {ReturnType} redirects + */ function makeRequireFunction(mod, redirects) { // lazy due to cycle const Module = lazyModule(); @@ -86,6 +112,7 @@ function makeRequireFunction(mod, redirects) { throw new ERR_INVALID_ARG_TYPE('mod', 'Module', mod); } + /** @type {(specifier: string) => unknown} */ let require; if (redirects) { const id = mod.filename || mod.id; @@ -131,6 +158,11 @@ function makeRequireFunction(mod, redirects) { }; } + /** + * The `resolve` method that gets attached to module-scope `require`. + * @param {string} request + * @param {Parameters[3]} options + */ function resolve(request, options) { validateString(request, 'request'); return Module._resolveFilename(request, mod, false, options); @@ -138,6 +170,10 @@ function makeRequireFunction(mod, redirects) { require.resolve = resolve; + /** + * The `paths` method that gets attached to module-scope `require`. + * @param {string} request + */ function paths(request) { validateString(request, 'request'); return Module._resolveLookupPaths(request, mod); @@ -159,6 +195,7 @@ function makeRequireFunction(mod, redirects) { * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) * because the buffer-to-string conversion in `fs.readFileSync()` * translates it to FEFF, the UTF-16 BOM. + * @param {string} content */ function stripBOM(content) { if (StringPrototypeCharCodeAt(content) === 0xFEFF) { @@ -167,6 +204,11 @@ function stripBOM(content) { return content; } +/** + * Add built-in modules to a global or REPL scope object. + * @param {object} object The object such as `globalThis` to add the built-in modules to. + * @param {string} dummyModuleName The label representing the set of built-in modules to add. + */ function addBuiltinLibsToObject(object, dummyModuleName) { // Make built-in modules available directly (loaded lazily). const Module = require('internal/modules/cjs/loader').Module; @@ -227,9 +269,8 @@ function addBuiltinLibsToObject(object, dummyModuleName) { } /** - * + * If a referrer is an URL instance or absolute path, convert it into an URL string. * @param {string | URL} referrer - * @returns {string} */ function normalizeReferrerURL(referrer) { if (typeof referrer === 'string' && path.isAbsolute(referrer)) { @@ -238,7 +279,10 @@ function normalizeReferrerURL(referrer) { return new URL(referrer).href; } -// For error messages only - used to check if ESM syntax is in use. +/** + * For error messages only, check if ESM syntax is in use. + * @param {string} code + */ function hasEsmSyntax(code) { debug('Checking for ESM syntax'); const parser = require('internal/deps/acorn/acorn/dist/acorn').Parser; diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js index e8d0364359693c..aa676caeb2be4b 100644 --- a/lib/internal/modules/run_main.js +++ b/lib/internal/modules/run_main.js @@ -7,6 +7,10 @@ const { const { getOptionValue } = require('internal/options'); const path = require('path'); +/** + * Get the absolute path to the main entry point. + * @param {string} main Entry point path + */ function resolveMainPath(main) { // Note extension resolution for the main entry point can be deprecated in a // future major. @@ -21,6 +25,10 @@ function resolveMainPath(main) { return mainPath; } +/** + * Determine whether the main entry point should be loaded through the ESM Loader. + * @param {string} mainPath Absolute path to the main entry point + */ function shouldUseESMLoader(mainPath) { /** * @type {string[]} userLoaders A list of custom loaders registered by the user @@ -41,6 +49,10 @@ function shouldUseESMLoader(mainPath) { return pkg && pkg.data.type === 'module'; } +/** + * Run the main entry point through the ESM Loader. + * @param {string} mainPath Absolute path to the main entry point + */ function runMainESM(mainPath) { const { loadESM } = require('internal/process/esm_loader'); const { pathToFileURL } = require('internal/url'); @@ -52,6 +64,10 @@ function runMainESM(mainPath) { })); } +/** + * Handle process exit events around the main entry point promise. + * @param {Promise} promise Main entry point promise + */ async function handleMainPromise(promise) { const { handleProcessExit, @@ -64,9 +80,12 @@ async function handleMainPromise(promise) { } } -// For backwards compatibility, we have to run a bunch of -// monkey-patchable code that belongs to the CJS loader (exposed by -// `require('module')`) even when the entry point is ESM. +/** + * Parse the CLI main entry point string and run it. + * For backwards compatibility, we have to run a bunch of monkey-patchable code that belongs to the CJS loader (exposed + * by `require('module')`) even when the entry point is ESM. + * @param {string} main CLI main entry point string + */ function executeUserEntryPoint(main = process.argv[1]) { const resolvedMain = resolveMainPath(main); const useESMLoader = shouldUseESMLoader(resolvedMain);