|
3 | 3 | const{ |
4 | 4 | ArrayPrototypeMap, |
5 | 5 | ArrayPrototypePush, |
6 | | - Boolean, |
7 | 6 | FunctionPrototypeCall, |
8 | 7 | JSONParse, |
9 | 8 | ObjectKeys, |
@@ -52,6 +51,7 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { |
52 | 51 | }); |
53 | 52 | const{ emitExperimentalWarning, kEmptyObject, setOwnProperty, isWindows }=require('internal/util'); |
54 | 53 | const{ |
| 54 | +ERR_INVALID_RETURN_PROPERTY_VALUE, |
55 | 55 | ERR_UNKNOWN_BUILTIN_MODULE, |
56 | 56 | }=require('internal/errors').codes; |
57 | 57 | const{ maybeCacheSourceMap }=require('internal/source_map/source_map_cache'); |
@@ -185,7 +185,7 @@ function createCJSModuleWrap(url, source, isMain, format, loadCJS = loadCJSModul |
185 | 185 | // In case the source was not provided by the `load` step, we need fetch it now. |
186 | 186 | source=stringify(source??getSource(newURL(url)).source); |
187 | 187 |
|
188 | | -const{ exportNames, module }=cjsPreparseModuleExports(filename,source,isMain,format); |
| 188 | +const{ exportNames, module }=cjsPreparseModuleExports(filename,source,format); |
189 | 189 | cjsCache.set(url,module); |
190 | 190 |
|
191 | 191 | constwrapperNames=[...exportNames,'module.exports']; |
@@ -229,6 +229,47 @@ function createCJSModuleWrap(url, source, isMain, format, loadCJS = loadCJSModul |
229 | 229 | },module); |
230 | 230 | } |
231 | 231 |
|
| 232 | +/** |
| 233 | + * Creates a ModuleWrap object for a CommonJS module without source texts. |
| 234 | + * @param {string} url - The URL of the module. |
| 235 | + * @param {boolean} isMain - Whether the module is the main module. |
| 236 | + * @returns {ModuleWrap} The ModuleWrap object for the CommonJS module. |
| 237 | + */ |
| 238 | +functioncreateCJSNoSourceModuleWrap(url,isMain){ |
| 239 | +debug(`Translating CJSModule without source ${url}`); |
| 240 | + |
| 241 | +constfilename=urlToFilename(url); |
| 242 | + |
| 243 | +constmodule=cjsEmplaceModuleCacheEntry(filename); |
| 244 | +cjsCache.set(url,module); |
| 245 | + |
| 246 | +if(isMain){ |
| 247 | +setOwnProperty(process,'mainModule',module); |
| 248 | +} |
| 249 | + |
| 250 | +// Addon export names are not known until the addon is loaded. |
| 251 | +constexportNames=['default','module.exports']; |
| 252 | +returnnewModuleWrap(url,undefined,exportNames,functionevaluationCallback(){ |
| 253 | +debug(`Loading CJSModule ${url}`); |
| 254 | + |
| 255 | +if(!module.loaded){ |
| 256 | +wrapModuleLoad(filename,null,isMain); |
| 257 | +} |
| 258 | + |
| 259 | +/** @type {import('./loader').ModuleExports} */ |
| 260 | +letexports; |
| 261 | +if(module[kModuleExport]!==undefined){ |
| 262 | +exports=module[kModuleExport]; |
| 263 | +module[kModuleExport]=undefined; |
| 264 | +}else{ |
| 265 | +({ exports }=module); |
| 266 | +} |
| 267 | + |
| 268 | +this.setExport('default',exports); |
| 269 | +this.setExport('module.exports',exports); |
| 270 | +},module); |
| 271 | +} |
| 272 | + |
232 | 273 | translators.set('commonjs-sync',functionrequireCommonJS(url,source,isMain){ |
233 | 274 | initCJSParseSync(); |
234 | 275 |
|
@@ -280,26 +321,38 @@ translators.set('commonjs', function commonjsStrategy(url, source, isMain) { |
280 | 321 | returncreateCJSModuleWrap(url,source,isMain,'commonjs',cjsLoader); |
281 | 322 | }); |
282 | 323 |
|
| 324 | +/** |
| 325 | + * Get or create an entry in the CJS module cache for the given filename. |
| 326 | + * @param {string} filename CJS module filename |
| 327 | + * @returns {CJSModule} the cached CJS module entry |
| 328 | + */ |
| 329 | +functioncjsEmplaceModuleCacheEntry(filename,exportNames){ |
| 330 | +// TODO: Do we want to keep hitting the user mutable CJS loader here? |
| 331 | +letcjsMod=CJSModule._cache[filename]; |
| 332 | +if(cjsMod){ |
| 333 | +returncjsMod; |
| 334 | +} |
| 335 | + |
| 336 | +cjsMod=newCJSModule(filename); |
| 337 | +cjsMod.filename=filename; |
| 338 | +cjsMod.paths=CJSModule._nodeModulePaths(cjsMod.path); |
| 339 | +cjsMod[kIsCachedByESMLoader]=true; |
| 340 | +CJSModule._cache[filename]=cjsMod; |
| 341 | + |
| 342 | +returncjsMod; |
| 343 | +} |
| 344 | + |
283 | 345 | /** |
284 | 346 | * Pre-parses a CommonJS module's exports and re-exports. |
285 | 347 | * @param {string} filename - The filename of the module. |
286 | 348 | * @param {string} [source] - The source code of the module. |
287 | | - * @param {boolean} isMain - Whether it is pre-parsing for the entry point. |
288 | | - * @param {string} format |
| 349 | + * @param {string} [format] |
289 | 350 | */ |
290 | | -functioncjsPreparseModuleExports(filename,source,isMain,format){ |
291 | | -letmodule=CJSModule._cache[filename]; |
292 | | -if(module&&module[kModuleExportNames]!==undefined){ |
| 351 | +functioncjsPreparseModuleExports(filename,source,format){ |
| 352 | +constmodule=cjsEmplaceModuleCacheEntry(filename); |
| 353 | +if(module[kModuleExportNames]!==undefined){ |
293 | 354 | return{ module,exportNames: module[kModuleExportNames]}; |
294 | 355 | } |
295 | | -constloaded=Boolean(module); |
296 | | -if(!loaded){ |
297 | | -module=newCJSModule(filename); |
298 | | -module.filename=filename; |
299 | | -module.paths=CJSModule._nodeModulePaths(module.path); |
300 | | -module[kIsCachedByESMLoader]=true; |
301 | | -CJSModule._cache[filename]=module; |
302 | | -} |
303 | 356 |
|
304 | 357 | if(source===undefined){ |
305 | 358 | ({ source }=loadSourceForCJSWithHooks(module,filename,format)); |
@@ -340,7 +393,7 @@ function cjsPreparseModuleExports(filename, source, isMain, format) { |
340 | 393 |
|
341 | 394 | if(format==='commonjs'|| |
342 | 395 | (!BuiltinModule.normalizeRequirableId(resolved)&&findLongestRegisteredExtension(resolved)==='.js')){ |
343 | | -const{exportNames: reexportNames}=cjsPreparseModuleExports(resolved,undefined,false,format); |
| 396 | +const{exportNames: reexportNames}=cjsPreparseModuleExports(resolved,undefined,format); |
344 | 397 | for(constnameofreexportNames){ |
345 | 398 | exportNames.add(name); |
346 | 399 | } |
@@ -462,6 +515,25 @@ translators.set('wasm', async function(url, source) { |
462 | 515 | }).module; |
463 | 516 | }); |
464 | 517 |
|
| 518 | +// Strategy for loading a addon |
| 519 | +translators.set('addon',functiontranslateAddon(url,source,isMain){ |
| 520 | +emitExperimentalWarning('Importing addons'); |
| 521 | + |
| 522 | +// The addon must be loaded from file system with dlopen. Assert |
| 523 | +// the source is null. |
| 524 | +if(source!==null){ |
| 525 | +thrownewERR_INVALID_RETURN_PROPERTY_VALUE( |
| 526 | +'null', |
| 527 | +'load', |
| 528 | +'source', |
| 529 | +source); |
| 530 | +} |
| 531 | + |
| 532 | +debug(`Translating addon ${url}`); |
| 533 | + |
| 534 | +returncreateCJSNoSourceModuleWrap(url,isMain); |
| 535 | +}); |
| 536 | + |
465 | 537 | // Strategy for loading a commonjs TypeScript module |
466 | 538 | translators.set('commonjs-typescript',function(url,source){ |
467 | 539 | emitExperimentalWarning('Type Stripping'); |
|
0 commit comments