在Module.prototype.require里Module._load();主要看这个函数

    1. Module._load = function(request, parent, isMain) {
    2. // 计算绝对路径
    3. var filename = Module._resolveFilename(request, parent);
    4. // 第一步:如果有缓存,取出缓存
    5. var cachedModule = Module._cache[filename];
    6. if (cachedModule) {
    7. return cachedModule.exports;
    8. // 第二步:是否为内置模块
    9. if (NativeModule.exists(filename)) {
    10. return NativeModule.require(filename);
    11. }
    12. // 第三步:生成模块实例,存入缓存
    13. var module = new Module(filename, parent);
    14. Module._cache[filename] = module;
    15. // 第四步:加载模块
    16. try {
    17. module.load(filename);
    18. hadException = false;
    19. } finally {
    20. if (hadException) {
    21. delete Module._cache[filename];
    22. }
    23. }
    24. // 第五步:输出模块的exports属性
    25. return module.exports;
    26. };

    阮一峰写的require博客:https://www.ruanyifeng.com/blog/2015/05/require.html
    nodejs里require的相关源码:https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L150

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