@@ -106,7 +106,6 @@ module.exports = {
106106 kModuleExportNames,
107107 kModuleCircularVisited,
108108 initializeCJS,
109- entryPointSource : undefined , // Set below.
110109 Module,
111110 wrapSafe,
112111 kIsMainSymbol,
@@ -1332,9 +1331,18 @@ function loadESMFromCJS(mod, filename) {
13321331 const source = getMaybeCachedSource ( mod , filename ) ;
13331332 const cascadedLoader = require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
13341333 const isMain = mod [ kIsMainSymbol ] ;
1335- // TODO(joyeecheung): we may want to invent optional special handling for default exports here.
1336- // For now, it's good enough to be identical to what `import()` returns.
1337- mod . exports = cascadedLoader . importSyncForRequire ( mod , filename , source , isMain , mod [ kModuleParent ] ) ;
1334+ if ( isMain ) {
1335+ require ( 'internal/modules/run_main' ) . runEntryPointWithESMLoader ( ( cascadedLoader ) => {
1336+ const mainURL = pathToFileURL ( filename ) . href ;
1337+ cascadedLoader . import ( mainURL , undefined , { __proto__ : null } , true ) ;
1338+ } ) ;
1339+ // ESM won't be accessible via process.mainModule.
1340+ setOwnProperty ( process , 'mainModule' , undefined ) ;
1341+ } else {
1342+ // TODO(joyeecheung): we may want to invent optional special handling for default exports here.
1343+ // For now, it's good enough to be identical to what `import()` returns.
1344+ mod . exports = cascadedLoader . importSyncForRequire ( mod , filename , source , isMain , mod [ kModuleParent ] ) ;
1345+ }
13381346}
13391347
13401348/**
@@ -1343,8 +1351,10 @@ function loadESMFromCJS(mod, filename) {
13431351 * @param {string } content The content of the file being loaded
13441352 * @param {Module } cjsModuleInstance The CommonJS loader instance
13451353 * @param {object } codeCache The SEA code cache
1354+ * @param {'commonjs'|undefined } format Intended format of the module.
13461355 */
1347- function wrapSafe ( filename , content , cjsModuleInstance , codeCache ) {
1356+ function wrapSafe ( filename , content , cjsModuleInstance , codeCache , format ) {
1357+ assert ( format !== 'module' ) ; // ESM should be handled in loadESMFromCJS().
13481358 const hostDefinedOptionId = vm_dynamic_import_default_internal ;
13491359 const importModuleDynamically = vm_dynamic_import_default_internal ;
13501360 if ( patched ) {
@@ -1374,46 +1384,33 @@ function wrapSafe(filename, content, cjsModuleInstance, codeCache) {
13741384 } ;
13751385 }
13761386
1377- try {
1378- const result = compileFunctionForCJSLoader ( content , filename ) ;
1379-
1380- // cachedDataRejected is only set for cache coming from SEA.
1381- if ( codeCache &&
1382- result . cachedDataRejected !== false &&
1383- internalBinding ( 'sea' ) . isSea ( ) ) {
1384- process . emitWarning ( 'Code cache data rejected.' ) ;
1385- }
1387+ const isMain = ! ! ( cjsModuleInstance && cjsModuleInstance [ kIsMainSymbol ] ) ;
1388+ const shouldDetectModule = ( format !== 'commonjs' && getOptionValue ( '--experimental-detect-module' ) ) ;
1389+ const result = compileFunctionForCJSLoader ( content , filename , isMain , shouldDetectModule ) ;
13861390
1387- // Cache the source map for the module if present.
1388- if ( result . sourceMapURL ) {
1389- maybeCacheSourceMap ( filename , content , this , false , undefined , result . sourceMapURL ) ;
1390- }
1391+ // cachedDataRejected is only set for cache coming from SEA.
1392+ if ( codeCache &&
1393+ result . cachedDataRejected !== false &&
1394+ internalBinding ( 'sea' ) . isSea ( ) ) {
1395+ process . emitWarning ( 'Code cache data rejected.' ) ;
1396+ }
13911397
1392- return result ;
1393- } catch ( err ) {
1394- if ( process . mainModule === cjsModuleInstance ) {
1395- if ( getOptionValue ( '--experimental-detect-module' ) ) {
1396- // For the main entry point, cache the source to potentially retry as ESM.
1397- module . exports . entryPointSource = content ;
1398- } else {
1399- // We only enrich the error (print a warning) if we're sure we're going to for-sure throw it; so if we're
1400- // retrying as ESM, wait until we know whether we're going to retry before calling `enrichCJSError`.
1401- const { enrichCJSError } = require ( 'internal/modules/esm/translators' ) ;
1402- enrichCJSError ( err , content , filename ) ;
1403- }
1404- }
1405- throw err ;
1398+ // Cache the source map for the module if present.
1399+ if ( result . sourceMapURL ) {
1400+ maybeCacheSourceMap ( filename , content , this , false , undefined , result . sourceMapURL ) ;
14061401 }
1402+
1403+ return result ;
14071404}
14081405
14091406/**
14101407 * Run the file contents in the correct scope or sandbox. Expose the correct helper variables (`require`, `module`,
14111408 * `exports`) to the file. Returns exception, if any.
14121409 * @param {string } content The source code of the module
14131410 * @param {string } filename The file path of the module
1414- * @param {boolean } loadAsESM Whether it's known to be ESM via .mjs or "type" in package.json .
1411+ * @param {'module'|'commonjs'|undefined } format Intended format of the module .
14151412 */
1416- Module . prototype . _compile = function ( content , filename , loadAsESM = false ) {
1413+ Module . prototype . _compile = function ( content , filename , format ) {
14171414 let moduleURL ;
14181415 let redirects ;
14191416 const manifest = policy ( ) ?. manifest ;
@@ -1423,17 +1420,24 @@ Module.prototype._compile = function(content, filename, loadAsESM = false) {
14231420 manifest . assertIntegrity ( moduleURL , content ) ;
14241421 }
14251422
1423+ let compiledWrapper ;
1424+ if ( format !== 'module' ) {
1425+ const result = wrapSafe ( filename , content , this , undefined , format ) ;
1426+ compiledWrapper = result . function ;
1427+ if ( result . canParseAsESM ) {
1428+ format = 'module' ;
1429+ }
1430+ }
1431+
14261432 // TODO(joyeecheung): when the module is the entry point, consider allowing TLA.
14271433 // Only modules being require()'d really need to avoid TLA.
1428- if ( loadAsESM ) {
1434+ if ( format === 'module' ) {
14291435 // Pass the source into the .mjs extension handler indirectly through the cache.
14301436 this [ kModuleSource ] = content ;
14311437 loadESMFromCJS ( this , filename ) ;
14321438 return ;
14331439 }
14341440
1435- const { function : compiledWrapper } = wrapSafe ( filename , content , this ) ;
1436-
14371441 // TODO(joyeecheung): the detection below is unnecessarily complex. Using the
14381442 // kIsMainSymbol, or a kBreakOnStartSymbol that gets passed from
14391443 // higher level instead of doing hacky detection here.
@@ -1510,12 +1514,13 @@ Module._extensions['.js'] = function(module, filename) {
15101514 // If already analyzed the source, then it will be cached.
15111515 const content = getMaybeCachedSource ( module , filename ) ;
15121516
1517+ let format ;
15131518 if ( StringPrototypeEndsWith ( filename , '.js' ) ) {
15141519 const pkg = packageJsonReader . getNearestParentPackageJSON ( filename ) ;
15151520 // Function require shouldn't be used in ES modules.
15161521 if ( pkg ?. data . type === 'module' ) {
15171522 if ( getOptionValue ( '--experimental-require-module' ) ) {
1518- module . _compile ( content , filename , true ) ;
1523+ module . _compile ( content , filename , 'module' ) ;
15191524 return ;
15201525 }
15211526
@@ -1549,10 +1554,14 @@ Module._extensions['.js'] = function(module, filename) {
15491554 }
15501555 }
15511556 throw err ;
1557+ } else if ( pkg ?. data . type === 'commonjs' ) {
1558+ format = 'commonjs' ;
15521559 }
1560+ } else if ( StringPrototypeEndsWith ( filename , '.cjs' ) ) {
1561+ format = 'commonjs' ;
15531562 }
15541563
1555- module . _compile ( content , filename , false ) ;
1564+ module . _compile ( content , filename , format ) ;
15561565} ;
15571566
15581567/**
0 commit comments