1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23 24const { 25 ArrayIsArray, 26 ArrayPrototypeJoin, 27 Error, 28 JSONParse, 29 Map, 30 ObjectCreate, 31 ObjectDefineProperty, 32 ObjectFreeze, 33 ObjectKeys, 34 ReflectSet, 35 RegExpPrototypeTest, 36 SafeMap, 37 SafeSet, 38 SafeWeakMap, 39 StringPrototypeEndsWith, 40 StringPrototypeIndexOf, 41 StringPrototypeLastIndexOf, 42 StringPrototypeMatch, 43 StringPrototypeSlice, 44 StringPrototypeStartsWith, 45} = primordials; 46 47// Map used to store CJS parsing data. 48const cjsParseCache = new SafeWeakMap(); 49 50// Set first due to cycle with ESM loader functions. 51module.exports = { 52 wrapSafe, Module, toRealPath, readPackageScope, cjsParseCache, 53 get hasLoadedAnyUserCJSModule() { return hasLoadedAnyUserCJSModule; } 54}; 55 56const { NativeModule } = require('internal/bootstrap/loaders'); 57const { 58 maybeCacheSourceMap, 59 rekeySourceMap 60} = require('internal/source_map/source_map_cache'); 61const { pathToFileURL, fileURLToPath, isURLInstance } = require('internal/url'); 62const { deprecate } = require('internal/util'); 63const vm = require('vm'); 64const assert = require('internal/assert'); 65const fs = require('fs'); 66const internalFS = require('internal/fs/utils'); 67const path = require('path'); 68const { sep } = path; 69const { internalModuleStat } = internalBinding('fs'); 70const packageJsonReader = require('internal/modules/package_json_reader'); 71const { safeGetenv } = internalBinding('credentials'); 72const { 73 makeRequireFunction, 74 normalizeReferrerURL, 75 stripBOM, 76 loadNativeModule 77} = require('internal/modules/cjs/helpers'); 78const { getOptionValue } = require('internal/options'); 79const enableSourceMaps = getOptionValue('--enable-source-maps'); 80const preserveSymlinks = getOptionValue('--preserve-symlinks'); 81const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); 82const manifest = getOptionValue('--experimental-policy') ? 83 require('internal/process/policy').manifest : 84 null; 85const { compileFunction } = internalBinding('contextify'); 86const userConditions = getOptionValue('--conditions'); 87 88// Whether any user-provided CJS modules had been loaded (executed). 89// Used for internal assertions. 90let hasLoadedAnyUserCJSModule = false; 91 92const { 93 ERR_INVALID_ARG_VALUE, 94 ERR_INVALID_OPT_VALUE, 95 ERR_INVALID_MODULE_SPECIFIER, 96 ERR_REQUIRE_ESM 97} = require('internal/errors').codes; 98const { validateString } = require('internal/validators'); 99const pendingDeprecation = getOptionValue('--pending-deprecation'); 100 101const { 102 CHAR_FORWARD_SLASH, 103 CHAR_BACKWARD_SLASH, 104 CHAR_COLON 105} = require('internal/constants'); 106 107const asyncESM = require('internal/process/esm_loader'); 108const { enrichCJSError } = require('internal/modules/esm/translators'); 109const { kEvaluated } = internalBinding('module_wrap'); 110const { 111 encodedSepRegEx, 112 packageExportsResolve, 113 packageImportsResolve 114} = require('internal/modules/esm/resolve'); 115 116const isWindows = process.platform === 'win32'; 117 118const relativeResolveCache = ObjectCreate(null); 119 120let requireDepth = 0; 121let statCache = null; 122 123function stat(filename) { 124 filename = path.toNamespacedPath(filename); 125 if (statCache !== null) { 126 const result = statCache.get(filename); 127 if (result !== undefined) return result; 128 } 129 const result = internalModuleStat(filename); 130 if (statCache !== null) statCache.set(filename, result); 131 return result; 132} 133 134function updateChildren(parent, child, scan) { 135 const children = parent && parent.children; 136 if (children && !(scan && children.includes(child))) 137 children.push(child); 138} 139 140function Module(id = '', parent) { 141 this.id = id; 142 this.path = path.dirname(id); 143 this.exports = {}; 144 this.parent = parent; 145 updateChildren(parent, this, false); 146 this.filename = null; 147 this.loaded = false; 148 this.children = []; 149} 150 151const builtinModules = []; 152for (const [id, mod] of NativeModule.map) { 153 if (mod.canBeRequiredByUsers) { 154 builtinModules.push(id); 155 } 156} 157 158ObjectFreeze(builtinModules); 159Module.builtinModules = builtinModules; 160 161Module._cache = ObjectCreate(null); 162Module._pathCache = ObjectCreate(null); 163Module._extensions = ObjectCreate(null); 164let modulePaths = []; 165Module.globalPaths = []; 166 167let patched = false; 168 169// eslint-disable-next-line func-style 170let wrap = function(script) { 171 return Module.wrapper[0] + script + Module.wrapper[1]; 172}; 173 174const wrapper = [ 175 '(function (exports, require, module, __filename, __dirname) { ', 176 '\n});' 177]; 178 179let wrapperProxy = new Proxy(wrapper, { 180 set(target, property, value, receiver) { 181 patched = true; 182 return ReflectSet(target, property, value, receiver); 183 }, 184 185 defineProperty(target, property, descriptor) { 186 patched = true; 187 return ObjectDefineProperty(target, property, descriptor); 188 } 189}); 190 191ObjectDefineProperty(Module, 'wrap', { 192 get() { 193 return wrap; 194 }, 195 196 set(value) { 197 patched = true; 198 wrap = value; 199 } 200}); 201 202ObjectDefineProperty(Module, 'wrapper', { 203 get() { 204 return wrapperProxy; 205 }, 206 207 set(value) { 208 patched = true; 209 wrapperProxy = value; 210 } 211}); 212 213let debug = require('internal/util/debuglog').debuglog('module', (fn) => { 214 debug = fn; 215}); 216Module._debug = deprecate(debug, 'Module._debug is deprecated.', 'DEP0077'); 217 218// Given a module name, and a list of paths to test, returns the first 219// matching file in the following precedence. 220// 221// require("a.<ext>") 222// -> a.<ext> 223// 224// require("a") 225// -> a 226// -> a.<ext> 227// -> a/index.<ext> 228 229const packageJsonCache = new SafeMap(); 230 231function readPackage(requestPath) { 232 const jsonPath = path.resolve(requestPath, 'package.json'); 233 234 const existing = packageJsonCache.get(jsonPath); 235 if (existing !== undefined) return existing; 236 237 const result = packageJsonReader.read(jsonPath); 238 const json = result.containsKeys === false ? '{}' : result.string; 239 if (json === undefined) { 240 packageJsonCache.set(jsonPath, false); 241 return false; 242 } 243 244 try { 245 const parsed = JSONParse(json); 246 const filtered = { 247 name: parsed.name, 248 main: parsed.main, 249 exports: parsed.exports, 250 imports: parsed.imports, 251 type: parsed.type 252 }; 253 packageJsonCache.set(jsonPath, filtered); 254 return filtered; 255 } catch (e) { 256 e.path = jsonPath; 257 e.message = 'Error parsing ' + jsonPath + ': ' + e.message; 258 throw e; 259 } 260} 261 262function readPackageScope(checkPath) { 263 const rootSeparatorIndex = StringPrototypeIndexOf(checkPath, sep); 264 let separatorIndex; 265 do { 266 separatorIndex = StringPrototypeLastIndexOf(checkPath, sep); 267 checkPath = StringPrototypeSlice(checkPath, 0, separatorIndex); 268 if (StringPrototypeEndsWith(checkPath, sep + 'node_modules')) 269 return false; 270 const pjson = readPackage(checkPath + sep); 271 if (pjson) return { 272 data: pjson, 273 path: checkPath, 274 }; 275 } while (separatorIndex > rootSeparatorIndex); 276 return false; 277} 278 279function tryPackage(requestPath, exts, isMain, originalPath) { 280 const pkg = readPackage(requestPath); 281 const pkgMain = pkg && pkg.main; 282 283 if (!pkgMain) { 284 return tryExtensions(path.resolve(requestPath, 'index'), exts, isMain); 285 } 286 287 const filename = path.resolve(requestPath, pkgMain); 288 let actual = tryFile(filename, isMain) || 289 tryExtensions(filename, exts, isMain) || 290 tryExtensions(path.resolve(filename, 'index'), exts, isMain); 291 if (actual === false) { 292 actual = tryExtensions(path.resolve(requestPath, 'index'), exts, isMain); 293 if (!actual) { 294 // eslint-disable-next-line no-restricted-syntax 295 const err = new Error( 296 `Cannot find module '${filename}'. ` + 297 'Please verify that the package.json has a valid "main" entry' 298 ); 299 err.code = 'MODULE_NOT_FOUND'; 300 err.path = path.resolve(requestPath, 'package.json'); 301 err.requestPath = originalPath; 302 // TODO(BridgeAR): Add the requireStack as well. 303 throw err; 304 } else if (pendingDeprecation) { 305 const jsonPath = path.resolve(requestPath, 'package.json'); 306 process.emitWarning( 307 `Invalid 'main' field in '${jsonPath}' of '${pkgMain}'. ` + 308 'Please either fix that or report it to the module author', 309 'DeprecationWarning', 310 'DEP0128' 311 ); 312 } 313 } 314 return actual; 315} 316 317// In order to minimize unnecessary lstat() calls, 318// this cache is a list of known-real paths. 319// Set to an empty Map to reset. 320const realpathCache = new Map(); 321 322// Check if the file exists and is not a directory 323// if using --preserve-symlinks and isMain is false, 324// keep symlinks intact, otherwise resolve to the 325// absolute realpath. 326function tryFile(requestPath, isMain) { 327 const rc = stat(requestPath); 328 if (rc !== 0) return; 329 if (preserveSymlinks && !isMain) { 330 return path.resolve(requestPath); 331 } 332 return toRealPath(requestPath); 333} 334 335function toRealPath(requestPath) { 336 return fs.realpathSync(requestPath, { 337 [internalFS.realpathCacheKey]: realpathCache 338 }); 339} 340 341// Given a path, check if the file exists with any of the set extensions 342function tryExtensions(p, exts, isMain) { 343 for (let i = 0; i < exts.length; i++) { 344 const filename = tryFile(p + exts[i], isMain); 345 346 if (filename) { 347 return filename; 348 } 349 } 350 return false; 351} 352 353// Find the longest (possibly multi-dot) extension registered in 354// Module._extensions 355function findLongestRegisteredExtension(filename) { 356 const name = path.basename(filename); 357 let currentExtension; 358 let index; 359 let startIndex = 0; 360 while ((index = name.indexOf('.', startIndex)) !== -1) { 361 startIndex = index + 1; 362 if (index === 0) continue; // Skip dotfiles like .gitignore 363 currentExtension = name.slice(index); 364 if (Module._extensions[currentExtension]) return currentExtension; 365 } 366 return '.js'; 367} 368 369function trySelfParentPath(parent) { 370 if (!parent) return false; 371 372 if (parent.filename) { 373 return parent.filename; 374 } else if (parent.id === '<repl>' || parent.id === 'internal/preload') { 375 try { 376 return process.cwd() + path.sep; 377 } catch { 378 return false; 379 } 380 } 381} 382 383function trySelf(parentPath, request) { 384 if (!parentPath) return false; 385 386 const { data: pkg, path: pkgPath } = readPackageScope(parentPath) || {}; 387 if (!pkg || pkg.exports === undefined) return false; 388 if (typeof pkg.name !== 'string') return false; 389 390 let expansion; 391 if (request === pkg.name) { 392 expansion = '.'; 393 } else if (StringPrototypeStartsWith(request, `${pkg.name}/`)) { 394 expansion = '.' + StringPrototypeSlice(request, pkg.name.length); 395 } else { 396 return false; 397 } 398 399 try { 400 return finalizeEsmResolution(packageExportsResolve( 401 pathToFileURL(pkgPath + '/package.json'), expansion, pkg, 402 pathToFileURL(parentPath), cjsConditions), request, parentPath, pkgPath); 403 } catch (e) { 404 if (e.code === 'ERR_MODULE_NOT_FOUND') 405 throw createEsmNotFoundErr(request, pkgPath + '/package.json'); 406 throw e; 407 } 408} 409 410// This only applies to requests of a specific form: 411// 1. name/.* 412// 2. @scope/name/.* 413const EXPORTS_PATTERN = /^((?:@[^/\\%]+\/)?[^./\\%][^/\\%]*)(\/.*)?$/; 414function resolveExports(nmPath, request) { 415 // The implementation's behavior is meant to mirror resolution in ESM. 416 const [, name, expansion = ''] = 417 StringPrototypeMatch(request, EXPORTS_PATTERN) || []; 418 if (!name) 419 return; 420 const pkgPath = path.resolve(nmPath, name); 421 const pkg = readPackage(pkgPath); 422 if (pkg && pkg.exports !== null && pkg.exports !== undefined) { 423 try { 424 return finalizeEsmResolution(packageExportsResolve( 425 pathToFileURL(pkgPath + '/package.json'), '.' + expansion, pkg, null, 426 cjsConditions), request, null, pkgPath); 427 } catch (e) { 428 if (e.code === 'ERR_MODULE_NOT_FOUND') 429 throw createEsmNotFoundErr(request, pkgPath + '/package.json'); 430 throw e; 431 } 432 } 433} 434 435const trailingSlashRegex = /(?:^|\/)\.?\.$/; 436Module._findPath = function(request, paths, isMain) { 437 const absoluteRequest = path.isAbsolute(request); 438 if (absoluteRequest) { 439 paths = ['']; 440 } else if (!paths || paths.length === 0) { 441 return false; 442 } 443 444 const cacheKey = request + '\x00' + 445 (paths.length === 1 ? paths[0] : paths.join('\x00')); 446 const entry = Module._pathCache[cacheKey]; 447 if (entry) 448 return entry; 449 450 let exts; 451 let trailingSlash = request.length > 0 && 452 request.charCodeAt(request.length - 1) === CHAR_FORWARD_SLASH; 453 if (!trailingSlash) { 454 trailingSlash = RegExpPrototypeTest(trailingSlashRegex, request); 455 } 456 457 // For each path 458 for (let i = 0; i < paths.length; i++) { 459 // Don't search further if path doesn't exist 460 const curPath = paths[i]; 461 if (curPath && stat(curPath) < 1) continue; 462 463 if (!absoluteRequest) { 464 const exportsResolved = resolveExports(curPath, request); 465 if (exportsResolved) 466 return exportsResolved; 467 } 468 469 const basePath = path.resolve(curPath, request); 470 let filename; 471 472 const rc = stat(basePath); 473 if (!trailingSlash) { 474 if (rc === 0) { // File. 475 if (!isMain) { 476 if (preserveSymlinks) { 477 filename = path.resolve(basePath); 478 } else { 479 filename = toRealPath(basePath); 480 } 481 } else if (preserveSymlinksMain) { 482 // For the main module, we use the preserveSymlinksMain flag instead 483 // mainly for backward compatibility, as the preserveSymlinks flag 484 // historically has not applied to the main module. Most likely this 485 // was intended to keep .bin/ binaries working, as following those 486 // symlinks is usually required for the imports in the corresponding 487 // files to resolve; that said, in some use cases following symlinks 488 // causes bigger problems which is why the preserveSymlinksMain option 489 // is needed. 490 filename = path.resolve(basePath); 491 } else { 492 filename = toRealPath(basePath); 493 } 494 } 495 496 if (!filename) { 497 // Try it with each of the extensions 498 if (exts === undefined) 499 exts = ObjectKeys(Module._extensions); 500 filename = tryExtensions(basePath, exts, isMain); 501 } 502 } 503 504 if (!filename && rc === 1) { // Directory. 505 // try it with each of the extensions at "index" 506 if (exts === undefined) 507 exts = ObjectKeys(Module._extensions); 508 filename = tryPackage(basePath, exts, isMain, request); 509 } 510 511 if (filename) { 512 Module._pathCache[cacheKey] = filename; 513 return filename; 514 } 515 } 516 517 return false; 518}; 519 520// 'node_modules' character codes reversed 521const nmChars = [ 115, 101, 108, 117, 100, 111, 109, 95, 101, 100, 111, 110 ]; 522const nmLen = nmChars.length; 523if (isWindows) { 524 // 'from' is the __dirname of the module. 525 Module._nodeModulePaths = function(from) { 526 // Guarantee that 'from' is absolute. 527 from = path.resolve(from); 528 529 // note: this approach *only* works when the path is guaranteed 530 // to be absolute. Doing a fully-edge-case-correct path.split 531 // that works on both Windows and Posix is non-trivial. 532 533 // return root node_modules when path is 'D:\\'. 534 // path.resolve will make sure from.length >=3 in Windows. 535 if (from.charCodeAt(from.length - 1) === CHAR_BACKWARD_SLASH && 536 from.charCodeAt(from.length - 2) === CHAR_COLON) 537 return [from + 'node_modules']; 538 539 const paths = []; 540 for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) { 541 const code = from.charCodeAt(i); 542 // The path segment separator check ('\' and '/') was used to get 543 // node_modules path for every path segment. 544 // Use colon as an extra condition since we can get node_modules 545 // path for drive root like 'C:\node_modules' and don't need to 546 // parse drive name. 547 if (code === CHAR_BACKWARD_SLASH || 548 code === CHAR_FORWARD_SLASH || 549 code === CHAR_COLON) { 550 if (p !== nmLen) 551 paths.push(from.slice(0, last) + '\\node_modules'); 552 last = i; 553 p = 0; 554 } else if (p !== -1) { 555 if (nmChars[p] === code) { 556 ++p; 557 } else { 558 p = -1; 559 } 560 } 561 } 562 563 return paths; 564 }; 565} else { // posix 566 // 'from' is the __dirname of the module. 567 Module._nodeModulePaths = function(from) { 568 // Guarantee that 'from' is absolute. 569 from = path.resolve(from); 570 // Return early not only to avoid unnecessary work, but to *avoid* returning 571 // an array of two items for a root: [ '//node_modules', '/node_modules' ] 572 if (from === '/') 573 return ['/node_modules']; 574 575 // note: this approach *only* works when the path is guaranteed 576 // to be absolute. Doing a fully-edge-case-correct path.split 577 // that works on both Windows and Posix is non-trivial. 578 const paths = []; 579 for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) { 580 const code = from.charCodeAt(i); 581 if (code === CHAR_FORWARD_SLASH) { 582 if (p !== nmLen) 583 paths.push(from.slice(0, last) + '/node_modules'); 584 last = i; 585 p = 0; 586 } else if (p !== -1) { 587 if (nmChars[p] === code) { 588 ++p; 589 } else { 590 p = -1; 591 } 592 } 593 } 594 595 // Append /node_modules to handle root paths. 596 paths.push('/node_modules'); 597 598 return paths; 599 }; 600} 601 602Module._resolveLookupPaths = function(request, parent) { 603 if (NativeModule.canBeRequiredByUsers(request)) { 604 debug('looking for %j in []', request); 605 return null; 606 } 607 608 // Check for node modules paths. 609 if (request.charAt(0) !== '.' || 610 (request.length > 1 && 611 request.charAt(1) !== '.' && 612 request.charAt(1) !== '/' && 613 (!isWindows || request.charAt(1) !== '\\'))) { 614 615 let paths = modulePaths; 616 if (parent != null && parent.paths && parent.paths.length) { 617 paths = parent.paths.concat(paths); 618 } 619 620 debug('looking for %j in %j', request, paths); 621 return paths.length > 0 ? paths : null; 622 } 623 624 // In REPL, parent.filename is null. 625 if (!parent || !parent.id || !parent.filename) { 626 // Make require('./path/to/foo') work - normally the path is taken 627 // from realpath(__filename) but in REPL there is no filename 628 const mainPaths = ['.']; 629 630 debug('looking for %j in %j', request, mainPaths); 631 return mainPaths; 632 } 633 634 debug('RELATIVE: requested: %s from parent.id %s', request, parent.id); 635 636 const parentDir = [path.dirname(parent.filename)]; 637 debug('looking for %j', parentDir); 638 return parentDir; 639}; 640 641// Check the cache for the requested file. 642// 1. If a module already exists in the cache: return its exports object. 643// 2. If the module is native: call 644// `NativeModule.prototype.compileForPublicLoader()` and return the exports. 645// 3. Otherwise, create a new module for the file and save it to the cache. 646// Then have it load the file contents before returning its exports 647// object. 648Module._load = function(request, parent, isMain) { 649 let relResolveCacheIdentifier; 650 if (parent) { 651 debug('Module._load REQUEST %s parent: %s', request, parent.id); 652 // Fast path for (lazy loaded) modules in the same directory. The indirect 653 // caching is required to allow cache invalidation without changing the old 654 // cache key names. 655 relResolveCacheIdentifier = `${parent.path}\x00${request}`; 656 const filename = relativeResolveCache[relResolveCacheIdentifier]; 657 if (filename !== undefined) { 658 const cachedModule = Module._cache[filename]; 659 if (cachedModule !== undefined) { 660 updateChildren(parent, cachedModule, true); 661 return cachedModule.exports; 662 } 663 delete relativeResolveCache[relResolveCacheIdentifier]; 664 } 665 } 666 667 const filename = Module._resolveFilename(request, parent, isMain); 668 669 const cachedModule = Module._cache[filename]; 670 if (cachedModule !== undefined) { 671 updateChildren(parent, cachedModule, true); 672 const parseCachedModule = cjsParseCache.get(cachedModule); 673 if (parseCachedModule && !parseCachedModule.loaded) 674 parseCachedModule.loaded = true; 675 else 676 return cachedModule.exports; 677 } 678 679 const mod = loadNativeModule(filename, request); 680 if (mod && mod.canBeRequiredByUsers) return mod.exports; 681 682 // Don't call updateChildren(), Module constructor already does. 683 const module = cachedModule || new Module(filename, parent); 684 685 if (isMain) { 686 process.mainModule = module; 687 module.id = '.'; 688 } 689 690 Module._cache[filename] = module; 691 if (parent !== undefined) { 692 relativeResolveCache[relResolveCacheIdentifier] = filename; 693 } 694 695 let threw = true; 696 try { 697 // Intercept exceptions that occur during the first tick and rekey them 698 // on error instance rather than module instance (which will immediately be 699 // garbage collected). 700 if (enableSourceMaps) { 701 try { 702 module.load(filename); 703 } catch (err) { 704 rekeySourceMap(Module._cache[filename], err); 705 throw err; /* node-do-not-add-exception-line */ 706 } 707 } else { 708 module.load(filename); 709 } 710 threw = false; 711 } finally { 712 if (threw) { 713 delete Module._cache[filename]; 714 if (parent !== undefined) { 715 delete relativeResolveCache[relResolveCacheIdentifier]; 716 const children = parent && parent.children; 717 if (ArrayIsArray(children)) { 718 const index = children.indexOf(module); 719 if (index !== -1) { 720 children.splice(index, 1); 721 } 722 } 723 } 724 } 725 } 726 727 return module.exports; 728}; 729 730const cjsConditions = new SafeSet(['require', 'node', ...userConditions]); 731Module._resolveFilename = function(request, parent, isMain, options) { 732 if (NativeModule.canBeRequiredByUsers(request)) { 733 return request; 734 } 735 736 let paths; 737 738 if (typeof options === 'object' && options !== null) { 739 if (ArrayIsArray(options.paths)) { 740 const isRelative = request.startsWith('./') || 741 request.startsWith('../') || 742 ((isWindows && request.startsWith('.\\')) || 743 request.startsWith('..\\')); 744 745 if (isRelative) { 746 paths = options.paths; 747 } else { 748 const fakeParent = new Module('', null); 749 750 paths = []; 751 752 for (let i = 0; i < options.paths.length; i++) { 753 const path = options.paths[i]; 754 fakeParent.paths = Module._nodeModulePaths(path); 755 const lookupPaths = Module._resolveLookupPaths(request, fakeParent); 756 757 for (let j = 0; j < lookupPaths.length; j++) { 758 if (!paths.includes(lookupPaths[j])) 759 paths.push(lookupPaths[j]); 760 } 761 } 762 } 763 } else if (options.paths === undefined) { 764 paths = Module._resolveLookupPaths(request, parent); 765 } else { 766 throw new ERR_INVALID_OPT_VALUE('options.paths', options.paths); 767 } 768 } else { 769 paths = Module._resolveLookupPaths(request, parent); 770 } 771 772 if (parent && parent.filename) { 773 if (request[0] === '#') { 774 const pkg = readPackageScope(parent.filename) || {}; 775 if (pkg.data && pkg.data.imports !== null && 776 pkg.data.imports !== undefined) { 777 try { 778 return finalizeEsmResolution( 779 packageImportsResolve(request, pathToFileURL(parent.filename), 780 cjsConditions), request, parent.filename, 781 pkg.path); 782 } catch (e) { 783 if (e.code === 'ERR_MODULE_NOT_FOUND') 784 throw createEsmNotFoundErr(request); 785 throw e; 786 } 787 } 788 } 789 } 790 791 // Try module self resoultion first 792 const parentPath = trySelfParentPath(parent); 793 const selfResolved = trySelf(parentPath, request); 794 if (selfResolved) { 795 const cacheKey = request + '\x00' + 796 (paths.length === 1 ? paths[0] : ArrayPrototypeJoin(paths, '\x00')); 797 Module._pathCache[cacheKey] = selfResolved; 798 return selfResolved; 799 } 800 801 // Look up the filename first, since that's the cache key. 802 const filename = Module._findPath(request, paths, isMain, false); 803 if (filename) return filename; 804 const requireStack = []; 805 for (let cursor = parent; 806 cursor; 807 cursor = cursor.parent) { 808 requireStack.push(cursor.filename || cursor.id); 809 } 810 let message = `Cannot find module '${request}'`; 811 if (requireStack.length > 0) { 812 message = message + '\nRequire stack:\n- ' + requireStack.join('\n- '); 813 } 814 // eslint-disable-next-line no-restricted-syntax 815 const err = new Error(message); 816 err.code = 'MODULE_NOT_FOUND'; 817 err.requireStack = requireStack; 818 throw err; 819}; 820 821function finalizeEsmResolution(match, request, parentPath, pkgPath) { 822 const { resolved, exact } = match; 823 if (StringPrototypeMatch(resolved, encodedSepRegEx)) 824 throw new ERR_INVALID_MODULE_SPECIFIER( 825 resolved, 'must not include encoded "/" or "\\" characters', parentPath); 826 const filename = fileURLToPath(resolved); 827 let actual = tryFile(filename); 828 if (!exact && !actual) { 829 const exts = ObjectKeys(Module._extensions); 830 actual = tryExtensions(filename, exts, false) || 831 tryPackage(filename, exts, false, request); 832 } 833 if (actual) 834 return actual; 835 const err = createEsmNotFoundErr(filename, 836 path.resolve(pkgPath, 'package.json')); 837 throw err; 838} 839 840function createEsmNotFoundErr(request, path) { 841 // eslint-disable-next-line no-restricted-syntax 842 const err = new Error(`Cannot find module '${request}'`); 843 err.code = 'MODULE_NOT_FOUND'; 844 if (path) 845 err.path = path; 846 // TODO(BridgeAR): Add the requireStack as well. 847 return err; 848} 849 850// Given a file name, pass it to the proper extension handler. 851Module.prototype.load = function(filename) { 852 debug('load %j for module %j', filename, this.id); 853 854 assert(!this.loaded); 855 this.filename = filename; 856 this.paths = Module._nodeModulePaths(path.dirname(filename)); 857 858 const extension = findLongestRegisteredExtension(filename); 859 // allow .mjs to be overridden 860 if (filename.endsWith('.mjs') && !Module._extensions['.mjs']) { 861 throw new ERR_REQUIRE_ESM(filename); 862 } 863 Module._extensions[extension](this, filename); 864 this.loaded = true; 865 866 const ESMLoader = asyncESM.ESMLoader; 867 // Create module entry at load time to snapshot exports correctly 868 const exports = this.exports; 869 // Preemptively cache 870 if ((!module || module.module === undefined || 871 module.module.getStatus() < kEvaluated) && 872 !ESMLoader.cjsCache.has(this)) 873 ESMLoader.cjsCache.set(this, exports); 874}; 875 876 877// Loads a module at the given file path. Returns that module's 878// `exports` property. 879Module.prototype.require = function(id) { 880 validateString(id, 'id'); 881 if (id === '') { 882 throw new ERR_INVALID_ARG_VALUE('id', id, 883 'must be a non-empty string'); 884 } 885 requireDepth++; 886 try { 887 return Module._load(id, this, /* isMain */ false); 888 } finally { 889 requireDepth--; 890 } 891}; 892 893 894// Resolved path to process.argv[1] will be lazily placed here 895// (needed for setting breakpoint when called with --inspect-brk) 896let resolvedArgv; 897let hasPausedEntry = false; 898 899function wrapSafe(filename, content, cjsModuleInstance) { 900 if (patched) { 901 const wrapper = Module.wrap(content); 902 return vm.runInThisContext(wrapper, { 903 filename, 904 lineOffset: 0, 905 displayErrors: true, 906 importModuleDynamically: async (specifier) => { 907 const loader = asyncESM.ESMLoader; 908 return loader.import(specifier, normalizeReferrerURL(filename)); 909 }, 910 }); 911 } 912 913 let compiled; 914 try { 915 compiled = compileFunction( 916 content, 917 filename, 918 0, 919 0, 920 undefined, 921 false, 922 undefined, 923 [], 924 [ 925 'exports', 926 'require', 927 'module', 928 '__filename', 929 '__dirname', 930 ] 931 ); 932 } catch (err) { 933 if (process.mainModule === cjsModuleInstance) 934 enrichCJSError(err); 935 throw err; 936 } 937 938 const { callbackMap } = internalBinding('module_wrap'); 939 callbackMap.set(compiled.cacheKey, { 940 importModuleDynamically: async (specifier) => { 941 const loader = asyncESM.ESMLoader; 942 return loader.import(specifier, normalizeReferrerURL(filename)); 943 } 944 }); 945 946 return compiled.function; 947} 948 949// Run the file contents in the correct scope or sandbox. Expose 950// the correct helper variables (require, module, exports) to 951// the file. 952// Returns exception, if any. 953Module.prototype._compile = function(content, filename) { 954 let moduleURL; 955 let redirects; 956 if (manifest) { 957 moduleURL = pathToFileURL(filename); 958 redirects = manifest.getRedirector(moduleURL); 959 manifest.assertIntegrity(moduleURL, content); 960 } 961 962 maybeCacheSourceMap(filename, content, this); 963 const compiledWrapper = wrapSafe(filename, content, this); 964 965 var inspectorWrapper = null; 966 if (getOptionValue('--inspect-brk') && process._eval == null) { 967 if (!resolvedArgv) { 968 // We enter the repl if we're not given a filename argument. 969 if (process.argv[1]) { 970 try { 971 resolvedArgv = Module._resolveFilename(process.argv[1], null, false); 972 } catch { 973 // We only expect this codepath to be reached in the case of a 974 // preloaded module (it will fail earlier with the main entry) 975 assert(ArrayIsArray(getOptionValue('--require'))); 976 } 977 } else { 978 resolvedArgv = 'repl'; 979 } 980 } 981 982 // Set breakpoint on module start 983 if (resolvedArgv && !hasPausedEntry && filename === resolvedArgv) { 984 hasPausedEntry = true; 985 inspectorWrapper = internalBinding('inspector').callAndPauseOnStart; 986 } 987 } 988 const dirname = path.dirname(filename); 989 const require = makeRequireFunction(this, redirects); 990 let result; 991 const exports = this.exports; 992 const thisValue = exports; 993 const module = this; 994 if (requireDepth === 0) statCache = new Map(); 995 if (inspectorWrapper) { 996 result = inspectorWrapper(compiledWrapper, thisValue, exports, 997 require, module, filename, dirname); 998 } else { 999 result = compiledWrapper.call(thisValue, exports, require, module, 1000 filename, dirname); 1001 } 1002 hasLoadedAnyUserCJSModule = true; 1003 if (requireDepth === 0) statCache = null; 1004 return result; 1005}; 1006 1007// Native extension for .js 1008Module._extensions['.js'] = function(module, filename) { 1009 if (filename.endsWith('.js')) { 1010 const pkg = readPackageScope(filename); 1011 // Function require shouldn't be used in ES modules. 1012 if (pkg && pkg.data && pkg.data.type === 'module') { 1013 const parentPath = module.parent && module.parent.filename; 1014 const packageJsonPath = path.resolve(pkg.path, 'package.json'); 1015 throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath); 1016 } 1017 } 1018 // If already analyzed the source, then it will be cached. 1019 const cached = cjsParseCache.get(module); 1020 let content; 1021 if (cached && cached.source) { 1022 content = cached.source; 1023 cached.source = undefined; 1024 } else { 1025 content = fs.readFileSync(filename, 'utf8'); 1026 } 1027 module._compile(content, filename); 1028}; 1029 1030 1031// Native extension for .json 1032Module._extensions['.json'] = function(module, filename) { 1033 const content = fs.readFileSync(filename, 'utf8'); 1034 1035 if (manifest) { 1036 const moduleURL = pathToFileURL(filename); 1037 manifest.assertIntegrity(moduleURL, content); 1038 } 1039 1040 try { 1041 module.exports = JSONParse(stripBOM(content)); 1042 } catch (err) { 1043 err.message = filename + ': ' + err.message; 1044 throw err; 1045 } 1046}; 1047 1048 1049// Native extension for .node 1050Module._extensions['.node'] = function(module, filename) { 1051 if (manifest) { 1052 const content = fs.readFileSync(filename); 1053 const moduleURL = pathToFileURL(filename); 1054 manifest.assertIntegrity(moduleURL, content); 1055 } 1056 // Be aware this doesn't use `content` 1057 return process.dlopen(module, path.toNamespacedPath(filename)); 1058}; 1059 1060function createRequireFromPath(filename) { 1061 // Allow a directory to be passed as the filename 1062 const trailingSlash = 1063 filename.endsWith('/') || (isWindows && filename.endsWith('\\')); 1064 1065 const proxyPath = trailingSlash ? 1066 path.join(filename, 'noop.js') : 1067 filename; 1068 1069 const m = new Module(proxyPath); 1070 m.filename = proxyPath; 1071 1072 m.paths = Module._nodeModulePaths(m.path); 1073 return makeRequireFunction(m, null); 1074} 1075 1076Module.createRequireFromPath = createRequireFromPath; 1077 1078const createRequireError = 'must be a file URL object, file URL string, or ' + 1079 'absolute path string'; 1080 1081function createRequire(filename) { 1082 let filepath; 1083 1084 if (isURLInstance(filename) || 1085 (typeof filename === 'string' && !path.isAbsolute(filename))) { 1086 try { 1087 filepath = fileURLToPath(filename); 1088 } catch { 1089 throw new ERR_INVALID_ARG_VALUE('filename', filename, 1090 createRequireError); 1091 } 1092 } else if (typeof filename !== 'string') { 1093 throw new ERR_INVALID_ARG_VALUE('filename', filename, createRequireError); 1094 } else { 1095 filepath = filename; 1096 } 1097 return createRequireFromPath(filepath); 1098} 1099 1100Module.createRequire = createRequire; 1101 1102Module._initPaths = function() { 1103 const homeDir = isWindows ? process.env.USERPROFILE : safeGetenv('HOME'); 1104 const nodePath = isWindows ? process.env.NODE_PATH : safeGetenv('NODE_PATH'); 1105 1106 // process.execPath is $PREFIX/bin/node except on Windows where it is 1107 // $PREFIX\node.exe where $PREFIX is the root of the Node.js installation. 1108 const prefixDir = isWindows ? 1109 path.resolve(process.execPath, '..') : 1110 path.resolve(process.execPath, '..', '..'); 1111 1112 let paths = [path.resolve(prefixDir, 'lib', 'node')]; 1113 1114 if (homeDir) { 1115 paths.unshift(path.resolve(homeDir, '.node_libraries')); 1116 paths.unshift(path.resolve(homeDir, '.node_modules')); 1117 } 1118 1119 if (nodePath) { 1120 paths = nodePath.split(path.delimiter).filter(function pathsFilterCB(path) { 1121 return !!path; 1122 }).concat(paths); 1123 } 1124 1125 modulePaths = paths; 1126 1127 // Clone as a shallow copy, for introspection. 1128 Module.globalPaths = modulePaths.slice(0); 1129}; 1130 1131Module._preloadModules = function(requests) { 1132 if (!ArrayIsArray(requests)) 1133 return; 1134 1135 // Preloaded modules have a dummy parent module which is deemed to exist 1136 // in the current working directory. This seeds the search path for 1137 // preloaded modules. 1138 const parent = new Module('internal/preload', null); 1139 try { 1140 parent.paths = Module._nodeModulePaths(process.cwd()); 1141 } catch (e) { 1142 if (e.code !== 'ENOENT') { 1143 throw e; 1144 } 1145 } 1146 for (let n = 0; n < requests.length; n++) 1147 parent.require(requests[n]); 1148}; 1149 1150Module.syncBuiltinESMExports = function syncBuiltinESMExports() { 1151 for (const mod of NativeModule.map.values()) { 1152 if (mod.canBeRequiredByUsers) { 1153 mod.syncExports(); 1154 } 1155 } 1156}; 1157 1158// Backwards compatibility 1159Module.Module = Module; 1160