@@ -52,6 +52,7 @@ const {
5252 ERR_UNKNOWN_BUILTIN_MODULE ,
5353} = require ( 'internal/errors' ) . codes ;
5454const { maybeCacheSourceMap } = require ( 'internal/source_map/source_map_cache' ) ;
55+ const { validateNull } = require ( 'internal/validators' ) ;
5556const moduleWrap = internalBinding ( 'module_wrap' ) ;
5657const { ModuleWrap } = moduleWrap ;
5758
@@ -225,6 +226,48 @@ function createCJSModuleWrap(url, source, isMain, loadCJS = loadCJSModule) {
225226 } , module ) ;
226227}
227228
229+ /**
230+ * Creates a ModuleWrap object for a CommonJS module without source texts.
231+ * @param {string } url - The URL of the module.
232+ * @param {boolean } isMain - Whether the module is the main module.
233+ * @returns {ModuleWrap } The ModuleWrap object for the CommonJS module.
234+ */
235+ function createCJSNoSourceModuleWrap ( url , isMain ) {
236+ debug ( `Translating CJSModule without source ${ url } ` ) ;
237+
238+ const filename = urlToFilename ( url ) ;
239+
240+ const { exportNames, module } = cjsEmplaceModuleCacheEntry ( filename ) ;
241+ if ( exportNames === undefined ) {
242+ // Addon export names are not known until the addon is loaded.
243+ module [ kModuleExportNames ] = [ 'default' , 'module.exports' ] ;
244+ }
245+ cjsCache . set ( url , module ) ;
246+
247+ if ( isMain ) {
248+ setOwnProperty ( process , 'mainModule' , module ) ;
249+ }
250+
251+ const wrapperNames = module [ kModuleExportNames ] ;
252+ return new ModuleWrap ( url , undefined , wrapperNames , function ( ) {
253+ debug ( `Loading CJSModule ${ url } ` ) ;
254+
255+ if ( ! module . loaded ) {
256+ wrapModuleLoad ( filename , null , isMain ) ;
257+ }
258+
259+ let exports ;
260+ if ( module [ kModuleExport ] !== undefined ) {
261+ exports = module [ kModuleExport ] ;
262+ module [ kModuleExport ] = undefined ;
263+ } else {
264+ ( { exports } = module ) ;
265+ }
266+ this . setExport ( 'default' , exports ) ;
267+ this . setExport ( 'module.exports' , exports ) ;
268+ } , module ) ;
269+ }
270+
228271translators . set ( 'commonjs-sync' , function requireCommonJS ( url , source , isMain ) {
229272 initCJSParseSync ( ) ;
230273
@@ -276,12 +319,7 @@ translators.set('commonjs', function commonjsStrategy(url, source, isMain) {
276319 return createCJSModuleWrap ( url , source , isMain , cjsLoader ) ;
277320} ) ;
278321
279- /**
280- * Pre-parses a CommonJS module's exports and re-exports.
281- * @param {string } filename - The filename of the module.
282- * @param {string } [source] - The source code of the module.
283- */
284- function cjsPreparseModuleExports ( filename , source ) {
322+ function cjsEmplaceModuleCacheEntry ( filename ) {
285323 // TODO: Do we want to keep hitting the user mutable CJS loader here?
286324 let module = CJSModule . _cache [ filename ] ;
287325 if ( module && module [ kModuleExportNames ] !== undefined ) {
@@ -293,10 +331,23 @@ function cjsPreparseModuleExports(filename, source) {
293331 module . filename = filename ;
294332 module . paths = CJSModule . _nodeModulePaths ( module . path ) ;
295333 module [ kIsCachedByESMLoader ] = true ;
296- module [ kModuleSource ] = source ;
297334 CJSModule . _cache [ filename ] = module ;
298335 }
299336
337+ return { module } ;
338+ }
339+
340+ /**
341+ * Pre-parses a CommonJS module's exports and re-exports.
342+ * @param {string } filename - The filename of the module.
343+ * @param {string } [source] - The source code of the module.
344+ */
345+ function cjsPreparseModuleExports ( filename , source ) {
346+ const { module, exportNames : cachedExportNames } = cjsEmplaceModuleCacheEntry ( filename ) ;
347+ if ( cachedExportNames !== undefined ) {
348+ return { module, exportNames : cachedExportNames } ;
349+ }
350+
300351 let exports , reexports ;
301352 try {
302353 ( { exports, reexports } = cjsParse ( source || '' ) ) ;
@@ -308,11 +359,10 @@ function cjsPreparseModuleExports(filename, source) {
308359 const exportNames = new SafeSet ( new SafeArrayIterator ( exports ) ) ;
309360
310361 // Set first for cycles.
362+ module [ kModuleSource ] = source ;
311363 module [ kModuleExportNames ] = exportNames ;
312364
313365 if ( reexports . length ) {
314- module . filename = filename ;
315- module . paths = CJSModule . _nodeModulePaths ( module . path ) ;
316366 for ( let i = 0 ; i < reexports . length ; i ++ ) {
317367 const reexport = reexports [ i ] ;
318368 let resolved ;
@@ -459,6 +509,19 @@ translators.set('wasm', async function(url, source) {
459509 } ) . module ;
460510} ) ;
461511
512+ // Strategy for loading a addon
513+ translators . set ( 'addon' , async function ( url , source , isMain ) {
514+ emitExperimentalWarning ( 'Importing addons' ) ;
515+
516+ // The addon must be loaded from file system with dlopen. Assert
517+ // the source is null.
518+ validateNull ( source , 'source' ) ;
519+
520+ debug ( `Translating addon ${ url } ` ) ;
521+
522+ return createCJSNoSourceModuleWrap ( url , isMain ) ;
523+ } ) ;
524+
462525// Strategy for loading a commonjs TypeScript module
463526translators . set ( 'commonjs-typescript' , function ( url , source ) {
464527 emitExperimentalWarning ( 'Type Stripping' ) ;
0 commit comments