|
2 | 2 |
|
3 | 3 | const{ |
4 | 4 | ArrayPrototypePush, |
5 | | - Boolean, |
6 | 5 | FunctionPrototypeCall, |
7 | 6 | JSONParse, |
8 | 7 | ObjectAssign, |
@@ -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'); |
@@ -186,7 +186,7 @@ function createCJSModuleWrap(url, source, isMain, format, loadCJS = loadCJSModul |
186 | 186 | // In case the source was not provided by the `load` step, we need fetch it now. |
187 | 187 | source=stringify(source??getSource(newURL(url)).source); |
188 | 188 |
|
189 | | -const{ exportNames, module }=cjsPreparseModuleExports(filename,source,isMain,format); |
| 189 | +const{ exportNames, module }=cjsPreparseModuleExports(filename,source,format); |
190 | 190 | cjsCache.set(url,module); |
191 | 191 | constnamesWithDefault=exportNames.has('default') ? |
192 | 192 | [...exportNames] : ['default', ...exportNames]; |
@@ -227,6 +227,47 @@ function createCJSModuleWrap(url, source, isMain, format, loadCJS = loadCJSModul |
227 | 227 | },module); |
228 | 228 | } |
229 | 229 |
|
| 230 | +/** |
| 231 | + * Creates a ModuleWrap object for a CommonJS module without source texts. |
| 232 | + * @param {string} url - The URL of the module. |
| 233 | + * @param {boolean} isMain - Whether the module is the main module. |
| 234 | + * @returns {ModuleWrap} The ModuleWrap object for the CommonJS module. |
| 235 | + */ |
| 236 | +functioncreateCJSNoSourceModuleWrap(url,isMain){ |
| 237 | +debug(`Translating CJSModule without source ${url}`); |
| 238 | + |
| 239 | +constfilename=urlToFilename(url); |
| 240 | + |
| 241 | +constmodule=cjsEmplaceModuleCacheEntry(filename); |
| 242 | +cjsCache.set(url,module); |
| 243 | + |
| 244 | +if(isMain){ |
| 245 | +setOwnProperty(process,'mainModule',module); |
| 246 | +} |
| 247 | + |
| 248 | +// Addon export names are not known until the addon is loaded. |
| 249 | +constexportNames=['default','module.exports']; |
| 250 | +returnnewModuleWrap(url,undefined,exportNames,functionevaluationCallback(){ |
| 251 | +debug(`Loading CJSModule ${url}`); |
| 252 | + |
| 253 | +if(!module.loaded){ |
| 254 | +wrapModuleLoad(filename,null,isMain); |
| 255 | +} |
| 256 | + |
| 257 | +/** @type {import('./loader').ModuleExports} */ |
| 258 | +letexports; |
| 259 | +if(module[kModuleExport]!==undefined){ |
| 260 | +exports=module[kModuleExport]; |
| 261 | +module[kModuleExport]=undefined; |
| 262 | +}else{ |
| 263 | +({ exports }=module); |
| 264 | +} |
| 265 | + |
| 266 | +this.setExport('default',exports); |
| 267 | +this.setExport('module.exports',exports); |
| 268 | +},module); |
| 269 | +} |
| 270 | + |
230 | 271 | translators.set('commonjs-sync',functionrequireCommonJS(url,source,isMain){ |
231 | 272 | initCJSParseSync(); |
232 | 273 |
|
@@ -277,26 +318,38 @@ translators.set('commonjs', function commonjsStrategy(url, source, isMain) { |
277 | 318 | returncreateCJSModuleWrap(url,source,isMain,'commonjs',cjsLoader); |
278 | 319 | }); |
279 | 320 |
|
| 321 | +/** |
| 322 | + * Get or create an entry in the CJS module cache for the given filename. |
| 323 | + * @param {string} filename CJS module filename |
| 324 | + * @returns {CJSModule} the cached CJS module entry |
| 325 | + */ |
| 326 | +functioncjsEmplaceModuleCacheEntry(filename,exportNames){ |
| 327 | +// TODO: Do we want to keep hitting the user mutable CJS loader here? |
| 328 | +letcjsMod=CJSModule._cache[filename]; |
| 329 | +if(cjsMod){ |
| 330 | +returncjsMod; |
| 331 | +} |
| 332 | + |
| 333 | +cjsMod=newCJSModule(filename); |
| 334 | +cjsMod.filename=filename; |
| 335 | +cjsMod.paths=CJSModule._nodeModulePaths(cjsMod.path); |
| 336 | +cjsMod[kIsCachedByESMLoader]=true; |
| 337 | +CJSModule._cache[filename]=cjsMod; |
| 338 | + |
| 339 | +returncjsMod; |
| 340 | +} |
| 341 | + |
280 | 342 | /** |
281 | 343 | * Pre-parses a CommonJS module's exports and re-exports. |
282 | 344 | * @param {string} filename - The filename of the module. |
283 | 345 | * @param {string} [source] - The source code of the module. |
284 | | - * @param {boolean} isMain - Whether it is pre-parsing for the entry point. |
285 | | - * @param {string} format |
| 346 | + * @param {string} [format] |
286 | 347 | */ |
287 | | -functioncjsPreparseModuleExports(filename,source,isMain,format){ |
288 | | -letmodule=CJSModule._cache[filename]; |
289 | | -if(module&&module[kModuleExportNames]!==undefined){ |
| 348 | +functioncjsPreparseModuleExports(filename,source,format){ |
| 349 | +constmodule=cjsEmplaceModuleCacheEntry(filename); |
| 350 | +if(module[kModuleExportNames]!==undefined){ |
290 | 351 | return{ module,exportNames: module[kModuleExportNames]}; |
291 | 352 | } |
292 | | -constloaded=Boolean(module); |
293 | | -if(!loaded){ |
294 | | -module=newCJSModule(filename); |
295 | | -module.filename=filename; |
296 | | -module.paths=CJSModule._nodeModulePaths(module.path); |
297 | | -module[kIsCachedByESMLoader]=true; |
298 | | -CJSModule._cache[filename]=module; |
299 | | -} |
300 | 353 |
|
301 | 354 | if(source===undefined){ |
302 | 355 | ({ source }=loadSourceForCJSWithHooks(module,filename,format)); |
@@ -337,7 +390,7 @@ function cjsPreparseModuleExports(filename, source, isMain, format) { |
337 | 390 |
|
338 | 391 | if(format==='commonjs'|| |
339 | 392 | (!BuiltinModule.normalizeRequirableId(resolved)&&findLongestRegisteredExtension(resolved)==='.js')){ |
340 | | -const{exportNames: reexportNames}=cjsPreparseModuleExports(resolved,undefined,false,format); |
| 393 | +const{exportNames: reexportNames}=cjsPreparseModuleExports(resolved,undefined,format); |
341 | 394 | for(constnameofreexportNames){ |
342 | 395 | exportNames.add(name); |
343 | 396 | } |
@@ -519,6 +572,25 @@ translators.set('wasm', function(url, source) { |
519 | 572 | returnmodule; |
520 | 573 | }); |
521 | 574 |
|
| 575 | +// Strategy for loading a addon |
| 576 | +translators.set('addon',functiontranslateAddon(url,source,isMain){ |
| 577 | +emitExperimentalWarning('Importing addons'); |
| 578 | + |
| 579 | +// The addon must be loaded from file system with dlopen. Assert |
| 580 | +// the source is null. |
| 581 | +if(source!==null){ |
| 582 | +thrownewERR_INVALID_RETURN_PROPERTY_VALUE( |
| 583 | +'null', |
| 584 | +'load', |
| 585 | +'source', |
| 586 | +source); |
| 587 | +} |
| 588 | + |
| 589 | +debug(`Translating addon ${url}`); |
| 590 | + |
| 591 | +returncreateCJSNoSourceModuleWrap(url,isMain); |
| 592 | +}); |
| 593 | + |
522 | 594 | // Strategy for loading a commonjs TypeScript module |
523 | 595 | translators.set('commonjs-typescript',function(url,source,isMain){ |
524 | 596 | assertBufferSource(source,true,'load'); |
|
0 commit comments