Skip to content

Latest commit

Β 

History

History
648 lines (583 loc) Β· 24.6 KB

File metadata and controls

648 lines (583 loc) Β· 24.6 KB
Β 
Jan 15, 2018
Jan 15, 2018
1
'use strict';
2
Apr 8, 2019
Apr 8, 2019
3
const {
Oct 2, 2024
Oct 2, 2024
4
ArrayPrototypePush,
Jul 24, 2024
Jul 24, 2024
5
FunctionPrototypeCall,
Nov 25, 2019
Nov 25, 2019
6
JSONParse,
May 27, 2025
May 27, 2025
7
ObjectAssign,
Apr 21, 2024
Apr 21, 2024
8
ObjectPrototypeHasOwnProperty,
Apr 8, 2019
Apr 8, 2019
9
SafeMap,
Sep 29, 2020
Sep 29, 2020
10
SafeSet,
May 27, 2025
May 27, 2025
11
SafeWeakMap,
Sep 29, 2023
Sep 29, 2023
12
StringPrototypeIncludes,
Aug 5, 2022
Aug 5, 2022
13
StringPrototypeReplaceAll,
Nov 14, 2020
Nov 14, 2020
14
StringPrototypeSlice,
Oct 1, 2020
Oct 1, 2020
15
StringPrototypeStartsWith,
Feb 19, 2026
Feb 19, 2026
16
globalThis,
Apr 8, 2019
Apr 8, 2019
17
} = primordials;
18
Mar 11, 2024
Mar 11, 2024
19
const {
20
compileFunctionForCJSLoader,
21
} = internalBinding('contextify');
22
Nov 29, 2023
Nov 29, 2023
23
const { BuiltinModule } = require('internal/bootstrap/realm');
Aug 13, 2023
Aug 13, 2023
24
const assert = require('internal/assert');
Apr 22, 2026
Apr 22, 2026
25
const fs = require('fs');
Dec 9, 2024
Dec 9, 2024
26
const { dirname, extname } = require('path');
Mar 15, 2018
Mar 15, 2018
27
const {
Aug 22, 2024
Aug 22, 2024
28
assertBufferSource,
Aug 8, 2022
Aug 8, 2022
29
loadBuiltinModule,
Aug 22, 2024
Aug 22, 2024
30
stringify,
Jul 26, 2019
Jul 26, 2019
31
stripBOM,
Apr 13, 2024
Apr 13, 2024
32
urlToFilename,
Dec 16, 2022
Dec 16, 2022
33
} = require('internal/modules/helpers');
Oct 24, 2024
Oct 24, 2024
34
const { stripTypeScriptModuleTypes } = require('internal/modules/typescript');
Sep 29, 2020
Sep 29, 2020
35
const {
Apr 8, 2024
Apr 8, 2024
36
kIsCachedByESMLoader,
37
Module: CJSModule,
May 30, 2024
May 30, 2024
38
wrapModuleLoad,
Apr 12, 2024
Apr 12, 2024
39
kModuleSource,
40
kModuleExport,
41
kModuleExportNames,
Dec 9, 2024
Dec 9, 2024
42
findLongestRegisteredExtension,
43
resolveForCJSWithHooks,
44
loadSourceForCJSWithHooks,
Sep 8, 2025
Sep 8, 2025
45
populateCJSExportsFromESM,
Sep 29, 2020
Sep 29, 2020
46
} = require('internal/modules/cjs/loader');
Aug 13, 2023
Aug 13, 2023
47
const { fileURLToPath, pathToFileURL, URL } = require('internal/url');
May 30, 2020
May 30, 2020
48
let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
49
debug = fn;
50
});
Jul 15, 2024
Jul 15, 2024
51
const { emitExperimentalWarning, kEmptyObject, setOwnProperty, isWindows } = require('internal/util');
May 21, 2020
May 21, 2020
52
const {
Dec 20, 2024
Dec 20, 2024
53
ERR_INVALID_RETURN_PROPERTY_VALUE,
May 21, 2020
May 21, 2020
54
ERR_UNKNOWN_BUILTIN_MODULE,
55
} = require('internal/errors').codes;
Oct 6, 2019
Oct 6, 2019
56
const { maybeCacheSourceMap } = require('internal/source_map/source_map_cache');
Oct 6, 2019
Oct 6, 2019
57
const moduleWrap = internalBinding('module_wrap');
Oct 31, 2025
Oct 31, 2025
58
const { ModuleWrap, kEvaluationPhase } = moduleWrap;
Mar 11, 2024
Mar 11, 2024
59
Feb 19, 2026
Feb 19, 2026
60
const { getSourceSync } = require('internal/modules/esm/load');
Nov 29, 2023
Nov 29, 2023
61
Jan 28, 2026
Jan 28, 2026
62
const { parse: cjsParse } = internalBinding('cjs_lexer');
Mar 18, 2024
Mar 18, 2024
63
Jan 15, 2018
Jan 15, 2018
64
const translators = new SafeMap();
Mar 27, 2019
Mar 27, 2019
65
exports.translators = translators;
Jan 15, 2018
Jan 15, 2018
66
Sep 19, 2023
Sep 19, 2023
67
/**
68
* Converts a URL to a file path if the URL protocol is 'file:'.
69
* @param {string} url - The URL to convert.
Jul 18, 2025
Jul 18, 2025
70
* @returns {string|URL}
Sep 19, 2023
Sep 19, 2023
71
*/
Aug 20, 2019
Aug 20, 2019
72
function errPath(url) {
73
const parsed = new URL(url);
74
if (parsed.protocol === 'file:') {
75
return fileURLToPath(parsed);
76
}
77
return url;
78
}
79
Sep 29, 2020
Sep 29, 2020
80
// Strategy for loading a standard JavaScript module.
Oct 14, 2025
Oct 14, 2025
81
translators.set('module', function moduleStrategy(url, translateContext, parentURL) {
82
let { source } = translateContext;
83
const isMain = (parentURL === undefined);
Sep 12, 2021
Sep 12, 2021
84
assertBufferSource(source, true, 'load');
May 21, 2020
May 21, 2020
85
source = stringify(source);
Oct 14, 2025
Oct 14, 2025
86
debug(`Translating StandardModule ${url}`, translateContext);
Feb 9, 2026
Feb 9, 2026
87
const {
88
compileSourceTextModule, SourceTextModuleTypes: { kUser },
89
} = require('internal/modules/esm/utils');
May 26, 2025
May 26, 2025
90
const context = isMain ? { isMain } : undefined;
Feb 9, 2026
Feb 9, 2026
91
const module = compileSourceTextModule(url, source, kUser, context);
Oct 6, 2019
Oct 6, 2019
92
return module;
Jan 15, 2018
Jan 15, 2018
93
});
94
Oct 31, 2025
Oct 31, 2025
95
const { requestTypes: { kRequireInImportedCJS } } = require('internal/modules/esm/utils');
Feb 2, 2026
Feb 2, 2026
96
const kShouldSkipModuleHooks = { __proto__: null, shouldSkipModuleHooks: true };
Mar 2, 2026
Mar 2, 2026
97
const kShouldNotSkipModuleHooks = { __proto__: null, shouldSkipModuleHooks: false };
98
Aug 13, 2023
Aug 13, 2023
99
/**
100
* Loads a CommonJS module via the ESM Loader sync CommonJS translator.
101
* This translator creates its own version of the `require` function passed into CommonJS modules.
102
* Any monkey patches applied to the CommonJS Loader will not affect this module.
103
* Any `require` calls in this module will load all children in the same way.
Sep 19, 2023
Sep 19, 2023
104
* @param {import('internal/modules/cjs/loader').Module} module - The module to load.
105
* @param {string} source - The source code of the module.
106
* @param {string} url - The URL of the module.
107
* @param {string} filename - The filename of the module.
Apr 29, 2024
Apr 29, 2024
108
* @param {boolean} isMain - Whether the module is the entrypoint
Aug 13, 2023
Aug 13, 2023
109
*/
Apr 29, 2024
Apr 29, 2024
110
function loadCJSModule(module, source, url, filename, isMain) {
Mar 17, 2026
Mar 17, 2026
111
// Use the full URL as the V8 resource name so that any search params
112
// (e.g. ?node-test-mock) are preserved in coverage reports.
113
const compileResult = compileFunctionForCJSLoader(source, url, false /* is_sea_main */, false);
Apr 29, 2024
Apr 29, 2024
114
May 30, 2025
May 30, 2025
115
const { function: compiledWrapper, sourceMapURL, sourceURL } = compileResult;
Feb 26, 2024
Feb 26, 2024
116
// Cache the source map for the cjs module if present.
May 28, 2024
May 28, 2024
117
if (sourceMapURL) {
May 30, 2025
May 30, 2025
118
maybeCacheSourceMap(url, source, module, false, sourceURL, sourceMapURL);
Feb 26, 2024
Feb 26, 2024
119
}
Mar 10, 2024
Mar 10, 2024
120
const cascadedLoader = require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
Aug 13, 2023
Aug 13, 2023
121
const __dirname = dirname(filename);
122
// eslint-disable-next-line func-name-matching,func-style
123
const requireFn = function require(specifier) {
Oct 14, 2023
Oct 14, 2023
124
let importAttributes = kEmptyObject;
Nov 29, 2023
Nov 29, 2023
125
if (!StringPrototypeStartsWith(specifier, 'node:') && !BuiltinModule.normalizeRequirableId(specifier)) {
Aug 13, 2023
Aug 13, 2023
126
// TODO: do not depend on the monkey-patchable CJS loader here.
127
const path = CJSModule._resolveFilename(specifier, module);
Nov 29, 2023
Nov 29, 2023
128
switch (extname(path)) {
129
case '.json':
130
importAttributes = { __proto__: null, type: 'json' };
131
break;
132
case '.node':
Feb 2, 2026
Feb 2, 2026
133
// If it gets here in the translators, the hooks must have already been invoked
134
// in the loader. Skip them in the synthetic module evaluation step.
135
return wrapModuleLoad(specifier, module, false, kShouldSkipModuleHooks);
Nov 29, 2023
Nov 29, 2023
136
default:
Aug 13, 2023
Aug 13, 2023
137
// fall through
138
}
Nov 29, 2023
Nov 29, 2023
139
specifier = `${pathToFileURL(path)}`;
Aug 13, 2023
Aug 13, 2023
140
}
Sep 8, 2025
Sep 8, 2025
141
Feb 9, 2026
Feb 9, 2026
142
// NOTE: This re-invented require() is only used on the loader-hook worker thread.
143
// On the main thread, the authentic require() is used instead (fixed by #60380).
Oct 31, 2025
Oct 31, 2025
144
const request = { specifier, attributes: importAttributes, phase: kEvaluationPhase, __proto__: null };
145
const job = cascadedLoader.getOrCreateModuleJob(url, request, kRequireInImportedCJS);
Aug 13, 2023
Aug 13, 2023
146
job.runSync();
Sep 17, 2025
Sep 17, 2025
147
let mod = cjsCache.get(job.url);
148
assert(job.module, `Imported CJS module ${url} failed to load module ${job.url} using require() due to race condition`);
149
150
if (job.module.synthetic) {
151
assert(mod, `Imported CJS module ${url} failed to load module ${job.url} using require() due to missed cache`);
152
return mod.exports;
153
}
154
155
// The module being required is a source text module.
156
if (!mod) {
157
mod = cjsEmplaceModuleCacheEntry(job.url);
158
cjsCache.set(job.url, mod);
159
}
160
// The module has been cached by the re-invented require. Update the exports object
161
// from the namespace object and return the evaluated exports.
162
if (!mod.loaded) {
Sep 8, 2025
Sep 8, 2025
163
debug('populateCJSExportsFromESM from require(esm) in imported CJS', url, mod, job.module);
164
populateCJSExportsFromESM(mod, job.module, job.module.getNamespace());
165
mod.loaded = true;
166
}
167
return mod.exports;
Aug 13, 2023
Aug 13, 2023
168
};
169
setOwnProperty(requireFn, 'resolve', function resolve(specifier) {
170
if (!StringPrototypeStartsWith(specifier, 'node:')) {
Mar 2, 2026
Mar 2, 2026
171
const {
172
filename, url: resolvedURL,
173
} = resolveForCJSWithHooks(specifier, module, false, kShouldNotSkipModuleHooks);
174
if (specifier !== filename) {
175
specifier = resolvedURL ?? `${pathToFileURL(filename)}`;
Aug 13, 2023
Aug 13, 2023
176
}
177
}
Oct 31, 2025
Oct 31, 2025
178
179
const request = { specifier, __proto__: null, attributes: kEmptyObject };
Mar 2, 2026
Mar 2, 2026
180
// Skip sync hooks in resolveSync since resolveForCJSWithHooks already ran them above.
181
const { url: resolvedURL } = cascadedLoader.resolveSync(url, request, /* shouldSkipSyncHooks */ true);
Apr 13, 2024
Apr 13, 2024
182
return urlToFilename(resolvedURL);
Aug 13, 2023
Aug 13, 2023
183
});
184
setOwnProperty(requireFn, 'main', process.mainModule);
185
Nov 27, 2025
Nov 27, 2025
186
FunctionPrototypeCall(compiledWrapper, module.exports,
187
module.exports, requireFn, module, filename, __dirname);
Aug 13, 2023
Aug 13, 2023
188
setOwnProperty(module, 'loaded', true);
189
}
190
191
// TODO: can we use a weak map instead?
192
const cjsCache = new SafeMap();
Sep 8, 2025
Sep 8, 2025
193
Sep 19, 2023
Sep 19, 2023
194
/**
195
* Creates a ModuleWrap object for a CommonJS module.
196
* @param {string} url - The URL of the module.
Oct 14, 2025
Oct 14, 2025
197
* @param {{ format: ModuleFormat, source: ModuleSource }} translateContext Context for the translator
198
* @param {string|undefined} parentURL URL of the module initiating the module loading for the first time.
199
* Undefined if it's the entry point.
Jul 18, 2025
Jul 18, 2025
200
* @param {typeof loadCJSModule} [loadCJS] - The function to load the CommonJS module.
Sep 19, 2023
Sep 19, 2023
201
* @returns {ModuleWrap} The ModuleWrap object for the CommonJS module.
202
*/
Oct 14, 2025
Oct 14, 2025
203
function createCJSModuleWrap(url, translateContext, parentURL, loadCJS = loadCJSModule) {
204
debug(`Translating CJSModule ${url}`, translateContext);
Sep 29, 2020
Sep 29, 2020
205
Oct 14, 2025
Oct 14, 2025
206
const { format: sourceFormat } = translateContext;
207
let { source } = translateContext;
208
const isMain = (parentURL === undefined);
Apr 13, 2024
Apr 13, 2024
209
const filename = urlToFilename(url);
Nov 29, 2023
Nov 29, 2023
210
// In case the source was not provided by the `load` step, we need fetch it now.
Feb 19, 2026
Feb 19, 2026
211
source = stringify(source ?? getSourceSync(new URL(url)).source);
Sep 29, 2020
Sep 29, 2020
212
Oct 14, 2025
Oct 14, 2025
213
const { exportNames, module } = cjsPreparseModuleExports(filename, source, sourceFormat);
Aug 13, 2023
Aug 13, 2023
214
cjsCache.set(url, module);
Oct 2, 2024
Oct 2, 2024
215
Mar 9, 2025
Mar 9, 2025
216
const wrapperNames = [...exportNames];
Oct 2, 2024
Oct 2, 2024
217
if (!exportNames.has('default')) {
218
ArrayPrototypePush(wrapperNames, 'default');
219
}
Mar 9, 2025
Mar 9, 2025
220
if (!exportNames.has('module.exports')) {
221
ArrayPrototypePush(wrapperNames, 'module.exports');
222
}
Sep 29, 2020
Sep 29, 2020
223
Aug 13, 2023
Aug 13, 2023
224
if (isMain) {
225
setOwnProperty(process, 'mainModule', module);
226
}
227
Oct 2, 2024
Oct 2, 2024
228
return new ModuleWrap(url, undefined, wrapperNames, function() {
Jan 15, 2018
Jan 15, 2018
229
debug(`Loading CJSModule ${url}`);
Sep 29, 2020
Sep 29, 2020
230
Aug 13, 2023
Aug 13, 2023
231
if (!module.loaded) {
Apr 29, 2024
Apr 29, 2024
232
loadCJS(module, source, url, filename, !!isMain);
Aug 13, 2023
Aug 13, 2023
233
}
234
Aug 9, 2020
Aug 9, 2020
235
let exports;
Apr 12, 2024
Apr 12, 2024
236
if (module[kModuleExport] !== undefined) {
237
exports = module[kModuleExport];
238
module[kModuleExport] = undefined;
Aug 9, 2020
Aug 9, 2020
239
} else {
Aug 13, 2023
Aug 13, 2023
240
({ exports } = module);
Sep 29, 2020
Sep 29, 2020
241
}
242
for (const exportName of exportNames) {
Mar 9, 2025
Mar 9, 2025
243
if (exportName === 'default' || exportName === 'module.exports' ||
244
!ObjectPrototypeHasOwnProperty(exports, exportName)) {
Sep 29, 2020
Sep 29, 2020
245
continue;
Sep 15, 2023
Sep 15, 2023
246
}
Sep 29, 2020
Sep 29, 2020
247
// We might trigger a getter -> dont fail.
248
let value;
249
try {
250
value = exports[exportName];
Feb 5, 2022
Feb 5, 2022
251
} catch {
252
// Continue regardless of error.
253
}
Sep 29, 2020
Sep 29, 2020
254
this.setExport(exportName, value);
Aug 9, 2020
Aug 9, 2020
255
}
256
this.setExport('default', exports);
Oct 2, 2024
Oct 2, 2024
257
this.setExport('module.exports', exports);
Apr 8, 2024
Apr 8, 2024
258
}, module);
Aug 13, 2023
Aug 13, 2023
259
}
260
Dec 20, 2024
Dec 20, 2024
261
/**
262
* Creates a ModuleWrap object for a CommonJS module without source texts.
263
* @param {string} url - The URL of the module.
Oct 14, 2025
Oct 14, 2025
264
* @param {string|undefined} parentURL - URL of the parent module, if any.
Dec 20, 2024
Dec 20, 2024
265
* @returns {ModuleWrap} The ModuleWrap object for the CommonJS module.
266
*/
Oct 14, 2025
Oct 14, 2025
267
function createCJSNoSourceModuleWrap(url, parentURL) {
Dec 20, 2024
Dec 20, 2024
268
debug(`Translating CJSModule without source ${url}`);
Oct 14, 2025
Oct 14, 2025
269
const isMain = (parentURL === undefined);
Dec 20, 2024
Dec 20, 2024
270
271
const filename = urlToFilename(url);
272
273
const module = cjsEmplaceModuleCacheEntry(filename);
274
cjsCache.set(url, module);
275
276
if (isMain) {
277
setOwnProperty(process, 'mainModule', module);
278
}
279
280
// Addon export names are not known until the addon is loaded.
281
const exportNames = ['default', 'module.exports'];
282
return new ModuleWrap(url, undefined, exportNames, function evaluationCallback() {
283
debug(`Loading CJSModule ${url}`);
284
285
if (!module.loaded) {
Feb 2, 2026
Feb 2, 2026
286
// If it gets here in the translators, the hooks must have already been invoked
287
// in the loader. Skip them in the synthetic module evaluation step.
288
wrapModuleLoad(filename, null, isMain, kShouldSkipModuleHooks);
Dec 20, 2024
Dec 20, 2024
289
}
290
291
/** @type {import('./loader').ModuleExports} */
292
let exports;
293
if (module[kModuleExport] !== undefined) {
294
exports = module[kModuleExport];
295
module[kModuleExport] = undefined;
296
} else {
297
({ exports } = module);
298
}
299
300
this.setExport('default', exports);
301
this.setExport('module.exports', exports);
302
}, module);
303
}
304
Oct 14, 2025
Oct 14, 2025
305
translators.set('commonjs-sync', function requireCommonJS(url, translateContext, parentURL) {
306
return createCJSModuleWrap(url, translateContext, parentURL, loadCJSModuleWithModuleLoad);
Mar 18, 2024
Mar 18, 2024
307
});
308
Aug 13, 2023
Aug 13, 2023
309
// Handle CommonJS modules referenced by `require` calls.
310
// This translator function must be sync, as `require` is sync.
Oct 14, 2025
Oct 14, 2025
311
translators.set('require-commonjs', (url, translateContext, parentURL) => {
312
return createCJSModuleWrap(url, translateContext, parentURL);
Jan 15, 2018
Jan 15, 2018
313
});
314
Jul 24, 2024
Jul 24, 2024
315
// Handle CommonJS modules referenced by `require` calls.
316
// This translator function must be sync, as `require` is sync.
Oct 14, 2025
Oct 14, 2025
317
translators.set('require-commonjs-typescript', (url, translateContext, parentURL) => {
318
translateContext.source = stripTypeScriptModuleTypes(stringify(translateContext.source), url);
319
return createCJSModuleWrap(url, translateContext, parentURL);
Jul 24, 2024
Jul 24, 2024
320
});
321
Oct 14, 2025
Oct 14, 2025
322
// This goes through Module._load to accommodate monkey-patchers.
323
function loadCJSModuleWithModuleLoad(module, source, url, filename, isMain) {
324
assert(module === CJSModule._cache[filename]);
Feb 2, 2026
Feb 2, 2026
325
// If it gets here in the translators, the hooks must have already been invoked
326
// in the loader. Skip them in the synthetic module evaluation step.
327
wrapModuleLoad(filename, undefined, isMain, kShouldSkipModuleHooks);
Oct 14, 2025
Oct 14, 2025
328
}
329
Aug 13, 2023
Aug 13, 2023
330
// Handle CommonJS modules referenced by `import` statements or expressions,
331
// or as the initial entry point when the ESM loader handles a CommonJS entry.
Oct 14, 2025
Oct 14, 2025
332
translators.set('commonjs', function commonjsStrategy(url, translateContext, parentURL) {
Aug 13, 2023
Aug 13, 2023
333
// For backward-compatibility, it's possible to return a nullish value for
Oct 14, 2025
Oct 14, 2025
334
// CJS source associated with a `file:` URL - that usually means the source is not
335
// customized (is loaded by default load) or the hook author wants it to be reloaded
336
// through CJS routine. In this case, the source is obtained by calling the
337
// monkey-patchable CJS loader.
338
// TODO(joyeecheung): just use wrapModuleLoad and let the CJS loader
339
// invoke the off-thread hooks. Use a special parent to avoid invoking in-thread
340
// hooks twice.
341
const shouldReloadByCJSLoader = (translateContext.shouldBeReloadedByCJSLoader || translateContext.source == null);
342
const cjsLoader = shouldReloadByCJSLoader ? loadCJSModuleWithModuleLoad : loadCJSModule;
Aug 13, 2023
Aug 13, 2023
343
344
try {
345
// We still need to read the FS to detect the exports.
Apr 22, 2026
Apr 22, 2026
346
// If you are reading this code to figure out how to patch Node.js module loading
347
// behavior - DO NOT depend on the patchability in new code: Node.js
348
// internals may stop going through the JavaScript fs module entirely.
349
// Prefer module.registerHooks() or other more formal fs hooks released in the future.
350
translateContext.source ??= fs.readFileSync(new URL(url), 'utf8');
Aug 13, 2023
Aug 13, 2023
351
} catch {
352
// Continue regardless of error.
353
}
Oct 14, 2025
Oct 14, 2025
354
return createCJSModuleWrap(url, translateContext, parentURL, cjsLoader);
Aug 13, 2023
Aug 13, 2023
355
});
356
Dec 20, 2024
Dec 20, 2024
357
/**
358
* Get or create an entry in the CJS module cache for the given filename.
359
* @param {string} filename CJS module filename
Sep 8, 2025
Sep 8, 2025
360
* @param {CJSModule} parent The parent CJS module
Dec 20, 2024
Dec 20, 2024
361
* @returns {CJSModule} the cached CJS module entry
362
*/
Sep 8, 2025
Sep 8, 2025
363
function cjsEmplaceModuleCacheEntry(filename, parent) {
Dec 20, 2024
Dec 20, 2024
364
// TODO: Do we want to keep hitting the user mutable CJS loader here?
365
let cjsMod = CJSModule._cache[filename];
366
if (cjsMod) {
367
return cjsMod;
368
}
369
Sep 8, 2025
Sep 8, 2025
370
cjsMod = new CJSModule(filename, parent);
Dec 20, 2024
Dec 20, 2024
371
cjsMod.filename = filename;
372
cjsMod.paths = CJSModule._nodeModulePaths(cjsMod.path);
373
cjsMod[kIsCachedByESMLoader] = true;
374
CJSModule._cache[filename] = cjsMod;
375
376
return cjsMod;
377
}
378
Sep 19, 2023
Sep 19, 2023
379
/**
380
* Pre-parses a CommonJS module's exports and re-exports.
381
* @param {string} filename - The filename of the module.
382
* @param {string} [source] - The source code of the module.
Dec 20, 2024
Dec 20, 2024
383
* @param {string} [format]
Jul 18, 2025
Jul 18, 2025
384
* @returns {{module: CJSModule, exportNames: string[]}}
Sep 19, 2023
Sep 19, 2023
385
*/
Dec 20, 2024
Dec 20, 2024
386
function cjsPreparseModuleExports(filename, source, format) {
387
const module = cjsEmplaceModuleCacheEntry(filename);
388
if (module[kModuleExportNames] !== undefined) {
Apr 12, 2024
Apr 12, 2024
389
return { module, exportNames: module[kModuleExportNames] };
Sep 29, 2020
Sep 29, 2020
390
}
391
Dec 9, 2024
Dec 9, 2024
392
if (source === undefined) {
393
({ source } = loadSourceForCJSWithHooks(module, filename, format));
394
}
395
module[kModuleSource] = source;
396
397
debug(`Preparsing exports of ${filename}`);
Jan 28, 2026
Jan 28, 2026
398
const { 0: exportNames, 1: reexports } = cjsParse(source);
Sep 29, 2020
Sep 29, 2020
399
400
// Set first for cycles.
Apr 12, 2024
Apr 12, 2024
401
module[kModuleExportNames] = exportNames;
Sep 29, 2020
Sep 29, 2020
402
Dec 9, 2024
Dec 9, 2024
403
// If there are any re-exports e.g. `module.exports = { ...require(...) }`,
404
// pre-parse the dependencies to find transitively exported names.
Sep 29, 2020
Sep 29, 2020
405
if (reexports.length) {
Dec 9, 2024
Dec 9, 2024
406
module.filename ??= filename;
407
module.paths ??= CJSModule._nodeModulePaths(dirname(filename));
408
Aug 13, 2023
Aug 13, 2023
409
for (let i = 0; i < reexports.length; i++) {
Dec 9, 2024
Dec 9, 2024
410
debug(`Preparsing re-exports of '${filename}'`);
Aug 13, 2023
Aug 13, 2023
411
const reexport = reexports[i];
412
let resolved;
Dec 9, 2024
Dec 9, 2024
413
let format;
Aug 13, 2023
Aug 13, 2023
414
try {
Mar 2, 2026
Mar 2, 2026
415
({ format, filename: resolved } = resolveForCJSWithHooks(reexport, module, false, kShouldNotSkipModuleHooks));
Dec 9, 2024
Dec 9, 2024
416
} catch (e) {
417
debug(`Failed to resolve '${reexport}', skipping`, e);
Aug 13, 2023
Aug 13, 2023
418
continue;
419
}
Dec 9, 2024
Dec 9, 2024
420
421
if (format === 'commonjs' ||
422
(!BuiltinModule.normalizeRequirableId(resolved) && findLongestRegisteredExtension(resolved) === '.js')) {
Dec 20, 2024
Dec 20, 2024
423
const { exportNames: reexportNames } = cjsPreparseModuleExports(resolved, undefined, format);
Sep 15, 2023
Sep 15, 2023
424
for (const name of reexportNames) {
Aug 13, 2023
Aug 13, 2023
425
exportNames.add(name);
Sep 15, 2023
Sep 15, 2023
426
}
Aug 13, 2023
Aug 13, 2023
427
}
Sep 29, 2020
Sep 29, 2020
428
}
Aug 13, 2023
Aug 13, 2023
429
}
Sep 29, 2020
Sep 29, 2020
430
431
return { module, exportNames };
432
}
433
Jan 15, 2018
Jan 15, 2018
434
// Strategy for loading a node builtin CommonJS module that isn't
435
// through normal resolution
Oct 14, 2025
Oct 14, 2025
436
translators.set('builtin', function builtinStrategy(url, translateContext) {
437
debug(`Translating BuiltinModule ${url}`, translateContext);
Sep 30, 2020
Sep 30, 2020
438
// Slice 'node:' scheme
Nov 14, 2020
Nov 14, 2020
439
const id = StringPrototypeSlice(url, 5);
Aug 8, 2022
Aug 8, 2022
440
const module = loadBuiltinModule(id, url);
Aug 13, 2023
Aug 13, 2023
441
cjsCache.set(url, module);
Nov 14, 2020
Nov 14, 2020
442
if (!StringPrototypeStartsWith(url, 'node:') || !module) {
Sep 30, 2020
Sep 30, 2020
443
throw new ERR_UNKNOWN_BUILTIN_MODULE(url);
Mar 18, 2019
Mar 18, 2019
444
}
Oct 6, 2019
Oct 6, 2019
445
debug(`Loading BuiltinModule ${url}`);
446
return module.getESMFacade();
Jan 15, 2018
Jan 15, 2018
447
});
448
Feb 14, 2018
Feb 14, 2018
449
// Strategy for loading a JSON file
Oct 14, 2025
Oct 14, 2025
450
translators.set('json', function jsonStrategy(url, translateContext) {
451
let { source } = translateContext;
Sep 12, 2021
Sep 12, 2021
452
assertBufferSource(source, true, 'load');
Mar 27, 2019
Mar 27, 2019
453
debug(`Loading JSONModule ${url}`);
Nov 14, 2020
Nov 14, 2020
454
const pathname = StringPrototypeStartsWith(url, 'file:') ?
455
fileURLToPath(url) : null;
Sep 29, 2023
Sep 29, 2023
456
const shouldCheckAndPopulateCJSModuleCache =
457
// We want to involve the CJS loader cache only for `file:` URL with no search query and no hash.
458
pathname && !StringPrototypeIncludes(url, '?') && !StringPrototypeIncludes(url, '#');
Aug 20, 2019
Aug 20, 2019
459
let modulePath;
460
let module;
Sep 29, 2023
Sep 29, 2023
461
if (shouldCheckAndPopulateCJSModuleCache) {
Aug 20, 2019
Aug 20, 2019
462
modulePath = isWindows ?
Aug 5, 2022
Aug 5, 2022
463
StringPrototypeReplaceAll(pathname, '/', '\\') : pathname;
Aug 20, 2019
Aug 20, 2019
464
module = CJSModule._cache[modulePath];
Sep 24, 2024
Sep 24, 2024
465
if (module?.loaded) {
Aug 20, 2019
Aug 20, 2019
466
const exports = module.exports;
Oct 14, 2019
Oct 14, 2019
467
return new ModuleWrap(url, undefined, ['default'], function() {
Oct 6, 2019
Oct 6, 2019
468
this.setExport('default', exports);
Oct 14, 2019
Oct 14, 2019
469
});
Aug 20, 2019
Aug 20, 2019
470
}
Mar 27, 2019
Mar 27, 2019
471
}
May 21, 2020
May 21, 2020
472
source = stringify(source);
Sep 29, 2023
Sep 29, 2023
473
if (shouldCheckAndPopulateCJSModuleCache) {
Aug 20, 2019
Aug 20, 2019
474
// A require call could have been called on the same file during loading and
475
// that resolves synchronously. To make sure we always return the identical
476
// export, we have to check again if the module already exists or not.
Aug 13, 2023
Aug 13, 2023
477
// TODO: remove CJS loader from here as well.
Aug 20, 2019
Aug 20, 2019
478
module = CJSModule._cache[modulePath];
Sep 24, 2024
Sep 24, 2024
479
if (module?.loaded) {
Aug 20, 2019
Aug 20, 2019
480
const exports = module.exports;
Oct 14, 2019
Oct 14, 2019
481
return new ModuleWrap(url, undefined, ['default'], function() {
Oct 6, 2019
Oct 6, 2019
482
this.setExport('default', exports);
Oct 14, 2019
Oct 14, 2019
483
});
Aug 20, 2019
Aug 20, 2019
484
}
Jun 15, 2019
Jun 15, 2019
485
}
Mar 27, 2019
Mar 27, 2019
486
try {
Jan 6, 2020
Jan 6, 2020
487
const exports = JSONParse(stripBOM(source));
Mar 27, 2019
Mar 27, 2019
488
module = {
489
exports,
Mar 6, 2023
Mar 6, 2023
490
loaded: true,
Mar 27, 2019
Mar 27, 2019
491
};
492
} catch (err) {
493
// TODO (BridgeAR): We could add a NodeCore error that wraps the JSON
494
// parse error instead of just manipulating the original error message.
495
// That would allow to add further properties and maybe additional
496
// debugging information.
Aug 20, 2019
Aug 20, 2019
497
err.message = errPath(url) + ': ' + err.message;
Mar 27, 2019
Mar 27, 2019
498
throw err;
499
}
Sep 29, 2023
Sep 29, 2023
500
if (shouldCheckAndPopulateCJSModuleCache) {
Aug 20, 2019
Aug 20, 2019
501
CJSModule._cache[modulePath] = module;
502
}
Aug 13, 2023
Aug 13, 2023
503
cjsCache.set(url, module);
Oct 14, 2019
Oct 14, 2019
504
return new ModuleWrap(url, undefined, ['default'], function() {
Mar 27, 2019
Mar 27, 2019
505
debug(`Parsing JSONModule ${url}`);
Oct 6, 2019
Oct 6, 2019
506
this.setExport('default', module.exports);
Oct 14, 2019
Oct 14, 2019
507
});
Jan 15, 2018
Jan 15, 2018
508
});
May 17, 2019
May 17, 2019
509
510
// Strategy for loading a wasm module
May 27, 2025
May 27, 2025
511
// This logic should collapse into WebAssembly Module Record in future.
512
/**
513
* @type {WeakMap<
514
* import('internal/modules/esm/utils').ModuleNamespaceObject,
515
* WebAssembly.Instance
516
* >} [[Instance]] slot proxy for WebAssembly Module Record
517
*/
518
const wasmInstances = new SafeWeakMap();
Oct 14, 2025
Oct 14, 2025
519
translators.set('wasm', function(url, translateContext) {
520
const { source } = translateContext;
Feb 19, 2026
Feb 19, 2026
521
// WebAssembly global is not available during snapshot building, so we need to get it lazily.
522
const { WebAssembly } = globalThis;
Sep 12, 2021
Sep 12, 2021
523
assertBufferSource(source, false, 'load');
524
Oct 14, 2025
Oct 14, 2025
525
debug(`Translating WASMModule ${url}`, translateContext);
Sep 12, 2021
Sep 12, 2021
526
May 17, 2019
May 17, 2019
527
let compiled;
528
try {
Aug 14, 2025
Aug 14, 2025
529
compiled = new WebAssembly.Module(source, {
Jul 18, 2025
Jul 18, 2025
530
builtins: ['js-string'],
Mar 14, 2026
Mar 14, 2026
531
importedStringConstants: 'wasm:js/string-constants',
Jul 18, 2025
Jul 18, 2025
532
});
May 17, 2019
May 17, 2019
533
} catch (err) {
Aug 20, 2019
Aug 20, 2019
534
err.message = errPath(url) + ': ' + err.message;
May 17, 2019
May 17, 2019
535
throw err;
536
}
537
May 27, 2025
May 27, 2025
538
const importsList = new SafeSet();
539
const wasmGlobalImports = [];
540
for (const impt of WebAssembly.Module.imports(compiled)) {
541
if (impt.kind === 'global') {
542
ArrayPrototypePush(wasmGlobalImports, impt);
543
}
Jul 18, 2025
Jul 18, 2025
544
// Prefix reservations per https://webassembly.github.io/esm-integration/js-api/index.html#parse-a-webassembly-module.
545
if (impt.module.startsWith('wasm-js:')) {
546
throw new WebAssembly.LinkError(`Invalid Wasm import "${impt.module}" in ${url}`);
547
}
548
if (impt.name.startsWith('wasm:') || impt.name.startsWith('wasm-js:')) {
549
throw new WebAssembly.LinkError(`Invalid Wasm import name "${impt.module}" in ${url}`);
550
}
May 27, 2025
May 27, 2025
551
importsList.add(impt.module);
552
}
553
554
const exportsList = new SafeSet();
555
const wasmGlobalExports = new SafeSet();
556
for (const expt of WebAssembly.Module.exports(compiled)) {
557
if (expt.kind === 'global') {
558
wasmGlobalExports.add(expt.name);
559
}
Jul 18, 2025
Jul 18, 2025
560
if (expt.name.startsWith('wasm:') || expt.name.startsWith('wasm-js:')) {
561
throw new WebAssembly.LinkError(`Invalid Wasm export name "${expt.name}" in ${url}`);
562
}
May 27, 2025
May 27, 2025
563
exportsList.add(expt.name);
564
}
May 17, 2019
May 17, 2019
565
May 27, 2025
May 27, 2025
566
const createDynamicModule = require('internal/modules/esm/create_dynamic_module');
567
568
const { module } = createDynamicModule([...importsList], [...exportsList], url, (reflect) => {
Jul 22, 2025
Jul 22, 2025
569
emitExperimentalWarning('Importing WebAssembly module instances');
May 27, 2025
May 27, 2025
570
for (const impt of importsList) {
571
const importNs = reflect.imports[impt];
572
const wasmInstance = wasmInstances.get(importNs);
573
if (wasmInstance) {
574
const wrappedModule = ObjectAssign({ __proto__: null }, reflect.imports[impt]);
575
for (const { module, name } of wasmGlobalImports) {
576
if (module !== impt) {
577
continue;
578
}
579
// Import of Wasm module global -> get direct WebAssembly.Global wrapped value.
580
// JS API validations otherwise remain the same.
581
wrappedModule[name] = wasmInstance[name];
582
}
583
reflect.imports[impt] = wrappedModule;
584
}
585
}
586
// In cycles importing unexecuted Wasm, wasmInstance will be undefined, which will fail during
587
// instantiation, since all bindings will be in the Temporal Deadzone (TDZ).
May 17, 2019
May 17, 2019
588
const { exports } = new WebAssembly.Instance(compiled, reflect.imports);
May 27, 2025
May 27, 2025
589
wasmInstances.set(module.getNamespace(), exports);
590
for (const expt of exportsList) {
591
let val = exports[expt];
592
// Unwrap WebAssembly.Global for JS bindings
593
if (wasmGlobalExports.has(expt)) {
594
try {
595
// v128 will throw in GetGlobalValue, see:
596
// https://webassembly.github.io/esm-integration/js-api/index.html#getglobalvalue
597
val = val.value;
598
} catch {
599
// v128 doesn't support ToJsValue() -> use undefined (ideally should stay in TDZ)
600
continue;
601
}
602
}
603
reflect.exports[expt].set(val);
Sep 15, 2023
Sep 15, 2023
604
}
Feb 28, 2025
Feb 28, 2025
605
});
606
// WebAssembly modules support source phase imports, to import the compiled module
607
// separate from the linked instance.
608
module.setModuleSourceObject(compiled);
609
return module;
May 17, 2019
May 17, 2019
610
});
Jul 24, 2024
Jul 24, 2024
611
Dec 20, 2024
Dec 20, 2024
612
// Strategy for loading a addon
Oct 14, 2025
Oct 14, 2025
613
translators.set('addon', function translateAddon(url, translateContext, parentURL) {
Dec 20, 2024
Dec 20, 2024
614
emitExperimentalWarning('Importing addons');
615
Oct 14, 2025
Oct 14, 2025
616
const { source } = translateContext;
Dec 20, 2024
Dec 20, 2024
617
// The addon must be loaded from file system with dlopen. Assert
618
// the source is null.
619
if (source !== null) {
620
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
621
'null',
622
'load',
623
'source',
624
source);
625
}
626
Oct 14, 2025
Oct 14, 2025
627
debug(`Translating addon ${url}`, translateContext);
Dec 20, 2024
Dec 20, 2024
628
Oct 14, 2025
Oct 14, 2025
629
return createCJSNoSourceModuleWrap(url, parentURL);
Dec 20, 2024
Dec 20, 2024
630
});
631
Jul 24, 2024
Jul 24, 2024
632
// Strategy for loading a commonjs TypeScript module
Oct 14, 2025
Oct 14, 2025
633
translators.set('commonjs-typescript', function(url, translateContext, parentURL) {
634
const { source } = translateContext;
Sep 19, 2024
Sep 19, 2024
635
assertBufferSource(source, true, 'load');
Oct 14, 2025
Oct 14, 2025
636
debug(`Translating TypeScript ${url}`, translateContext);
637
translateContext.source = stripTypeScriptModuleTypes(stringify(source), url);
638
return FunctionPrototypeCall(translators.get('commonjs'), this, url, translateContext, parentURL);
Jul 24, 2024
Jul 24, 2024
639
});
640
641
// Strategy for loading an esm TypeScript module
Oct 14, 2025
Oct 14, 2025
642
translators.set('module-typescript', function(url, translateContext, parentURL) {
643
const { source } = translateContext;
Sep 19, 2024
Sep 19, 2024
644
assertBufferSource(source, true, 'load');
Oct 14, 2025
Oct 14, 2025
645
debug(`Translating TypeScript ${url}`, translateContext);
646
translateContext.source = stripTypeScriptModuleTypes(stringify(source), url);
647
return FunctionPrototypeCall(translators.get('module'), this, url, translateContext, parentURL);
Jul 24, 2024
Jul 24, 2024
648
});