@@ -106,7 +106,6 @@ module.exports = {
106106 kModuleExportNames,
107107 kModuleCircularVisited,
108108 initializeCJS,
109- entryPointSource : undefined , // Set below.
110109 Module,
111110 wrapSafe,
112111 kIsMainSymbol,
@@ -1333,9 +1332,18 @@ function loadESMFromCJS(mod, filename) {
13331332 const source = getMaybeCachedSource ( mod , filename ) ;
13341333 const cascadedLoader = require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
13351334 const isMain = mod [ kIsMainSymbol ] ;
1336- // TODO(joyeecheung): we may want to invent optional special handling for default exports here.
1337- // For now, it's good enough to be identical to what `import()` returns.
1338- mod . exports = cascadedLoader . importSyncForRequire ( mod , filename , source , isMain , mod [ kModuleParent ] ) ;
1335+ if ( isMain ) {
1336+ require ( 'internal/modules/run_main' ) . runEntryPointWithESMLoader ( ( cascadedLoader ) => {
1337+ const mainURL = pathToFileURL ( filename ) . href ;
1338+ cascadedLoader . import ( mainURL , undefined , { __proto__ : null } , true ) ;
1339+ } ) ;
1340+ // ESM won't be accessible via process.mainModule.
1341+ setOwnProperty ( process , 'mainModule' , undefined ) ;
1342+ } else {
1343+ // TODO(joyeecheung): we may want to invent optional special handling for default exports here.
1344+ // For now, it's good enough to be identical to what `import()` returns.
1345+ mod . exports = cascadedLoader . importSyncForRequire ( mod , filename , source , isMain , mod [ kModuleParent ] ) ;
1346+ }
13391347}
13401348
13411349/**
@@ -1344,8 +1352,10 @@ function loadESMFromCJS(mod, filename) {
13441352 * @param {string } content The content of the file being loaded
13451353 * @param {Module } cjsModuleInstance The CommonJS loader instance
13461354 * @param {object } codeCache The SEA code cache
1355+ * @param {'commonjs'|undefined } format Intended format of the module.
13471356 */
1348- function wrapSafe ( filename , content , cjsModuleInstance , codeCache ) {
1357+ function wrapSafe ( filename , content , cjsModuleInstance , codeCache , format ) {
1358+ assert ( format !== 'module' ) ; // ESM should be handled in loadESMFromCJS().
13491359 const hostDefinedOptionId = vm_dynamic_import_default_internal ;
13501360 const importModuleDynamically = vm_dynamic_import_default_internal ;
13511361 if ( patched ) {
@@ -1375,46 +1385,33 @@ function wrapSafe(filename, content, cjsModuleInstance, codeCache) {
13751385 } ;
13761386 }
13771387
1378- try {
1379- const result = compileFunctionForCJSLoader ( content , filename ) ;
1380-
1381- // cachedDataRejected is only set for cache coming from SEA.
1382- if ( codeCache &&
1383- result . cachedDataRejected !== false &&
1384- internalBinding ( 'sea' ) . isSea ( ) ) {
1385- process . emitWarning ( 'Code cache data rejected.' ) ;
1386- }
1388+ const isMain = ! ! ( cjsModuleInstance && cjsModuleInstance [ kIsMainSymbol ] ) ;
1389+ const shouldDetectModule = ( format !== 'commonjs' && getOptionValue ( '--experimental-detect-module' ) ) ;
1390+ const result = compileFunctionForCJSLoader ( content , filename , isMain , shouldDetectModule ) ;
13871391
1388- // Cache the source map for the module if present.
1389- if ( result . sourceMapURL ) {
1390- maybeCacheSourceMap ( filename , content , this , false , undefined , result . sourceMapURL ) ;
1391- }
1392+ // cachedDataRejected is only set for cache coming from SEA.
1393+ if ( codeCache &&
1394+ result . cachedDataRejected !== false &&
1395+ internalBinding ( 'sea' ) . isSea ( ) ) {
1396+ process . emitWarning ( 'Code cache data rejected.' ) ;
1397+ }
13921398
1393- return result ;
1394- } catch ( err ) {
1395- if ( process . mainModule === cjsModuleInstance ) {
1396- if ( getOptionValue ( '--experimental-detect-module' ) ) {
1397- // For the main entry point, cache the source to potentially retry as ESM.
1398- module . exports . entryPointSource = content ;
1399- } else {
1400- // We only enrich the error (print a warning) if we're sure we're going to for-sure throw it; so if we're
1401- // retrying as ESM, wait until we know whether we're going to retry before calling `enrichCJSError`.
1402- const { enrichCJSError } = require ( 'internal/modules/esm/translators' ) ;
1403- enrichCJSError ( err , content , filename ) ;
1404- }
1405- }
1406- throw err ;
1399+ // Cache the source map for the module if present.
1400+ if ( result . sourceMapURL ) {
1401+ maybeCacheSourceMap ( filename , content , this , false , undefined , result . sourceMapURL ) ;
14071402 }
1403+
1404+ return result ;
14081405}
14091406
14101407/**
14111408 * Run the file contents in the correct scope or sandbox. Expose the correct helper variables (`require`, `module`,
14121409 * `exports`) to the file. Returns exception, if any.
14131410 * @param {string } content The source code of the module
14141411 * @param {string } filename The file path of the module
1415- * @param {boolean } loadAsESM Whether it's known to be ESM via .mjs or "type" in package.json .
1412+ * @param {'module'|'commonjs'|undefined } format Intended format of the module .
14161413 */
1417- Module . prototype . _compile = function ( content , filename , loadAsESM = false ) {
1414+ Module . prototype . _compile = function ( content , filename , format ) {
14181415 let moduleURL ;
14191416 let redirects ;
14201417 const manifest = policy ( ) ?. manifest ;
@@ -1424,17 +1421,24 @@ Module.prototype._compile = function(content, filename, loadAsESM = false) {
14241421 manifest . assertIntegrity ( moduleURL , content ) ;
14251422 }
14261423
1424+ let compiledWrapper ;
1425+ if ( format !== 'module' ) {
1426+ const result = wrapSafe ( filename , content , this , undefined , format ) ;
1427+ compiledWrapper = result . function ;
1428+ if ( result . canParseAsESM ) {
1429+ format = 'module' ;
1430+ }
1431+ }
1432+
14271433 // TODO(joyeecheung): when the module is the entry point, consider allowing TLA.
14281434 // Only modules being require()'d really need to avoid TLA.
1429- if ( loadAsESM ) {
1435+ if ( format === 'module' ) {
14301436 // Pass the source into the .mjs extension handler indirectly through the cache.
14311437 this [ kModuleSource ] = content ;
14321438 loadESMFromCJS ( this , filename ) ;
14331439 return ;
14341440 }
14351441
1436- const { function : compiledWrapper } = wrapSafe ( filename , content , this ) ;
1437-
14381442 // TODO(joyeecheung): the detection below is unnecessarily complex. Using the
14391443 // kIsMainSymbol, or a kBreakOnStartSymbol that gets passed from
14401444 // higher level instead of doing hacky detection here.
@@ -1511,12 +1515,13 @@ Module._extensions['.js'] = function(module, filename) {
15111515 // If already analyzed the source, then it will be cached.
15121516 const content = getMaybeCachedSource ( module , filename ) ;
15131517
1518+ let format ;
15141519 if ( StringPrototypeEndsWith ( filename , '.js' ) ) {
15151520 const pkg = packageJsonReader . readPackageScope ( filename ) || { __proto__ : null } ;
15161521 // Function require shouldn't be used in ES modules.
15171522 if ( pkg . data ?. type === 'module' ) {
15181523 if ( getOptionValue ( '--experimental-require-module' ) ) {
1519- module . _compile ( content , filename , true ) ;
1524+ module . _compile ( content , filename , 'module' ) ;
15201525 return ;
15211526 }
15221527
@@ -1550,10 +1555,14 @@ Module._extensions['.js'] = function(module, filename) {
15501555 }
15511556 }
15521557 throw err ;
1558+ } else if ( pkg . data ?. type === 'commonjs' ) {
1559+ format = 'commonjs' ;
15531560 }
1561+ } else if ( StringPrototypeEndsWith ( filename , '.cjs' ) ) {
1562+ format = 'commonjs' ;
15541563 }
15551564
1556- module . _compile ( content , filename , false ) ;
1565+ module . _compile ( content , filename , format ) ;
15571566} ;
15581567
15591568/**
0 commit comments