@@ -101,6 +101,9 @@ const kIsMainSymbol = Symbol('kIsMainSymbol');
101101const  kIsCachedByESMLoader  =  Symbol ( 'kIsCachedByESMLoader' ) ; 
102102const  kRequiredModuleSymbol  =  Symbol ( 'kRequiredModuleSymbol' ) ; 
103103const  kIsExecuting  =  Symbol ( 'kIsExecuting' ) ; 
104+ 
105+ const  kFormat  =  Symbol ( 'kFormat' ) ; 
106+ 
104107// Set first due to cycle with ESM loader functions. 
105108module . exports  =  { 
106109 kModuleSource, 
@@ -438,10 +441,6 @@ function initializeCJS() {
438441 // TODO(joyeecheung): deprecate this in favor of a proper hook? 
439442 Module . runMain  = 
440443 require ( 'internal/modules/run_main' ) . executeUserEntryPoint ; 
441- 
442-  if  ( getOptionValue ( '--experimental-require-module' ) )  { 
443-  Module . _extensions [ '.mjs' ]  =  loadESMFromCJS ; 
444-  } 
445444} 
446445
447446// Given a module name, and a list of paths to test, returns the first 
@@ -651,14 +650,7 @@ function resolveExports(nmPath, request) {
651650// We don't cache this in case user extends the extensions. 
652651function  getDefaultExtensions ( )  { 
653652 const  extensions  =  ObjectKeys ( Module . _extensions ) ; 
654-  if  ( ! getOptionValue ( '--experimental-require-module' ) )  { 
655-  return  extensions ; 
656-  } 
657-  // If the .mjs extension is added by --experimental-require-module, 
658-  // remove it from the supported default extensions to maintain 
659-  // compatibility. 
660-  // TODO(joyeecheung): allow both .mjs and .cjs? 
661-  return  ArrayPrototypeFilter ( extensions ,  ( ext )  =>  ext  !==  '.mjs'  ||  Module . _extensions [ '.mjs' ]  !==  loadESMFromCJS ) ; 
653+  return  extensions ; 
662654} 
663655
664656/** 
@@ -1270,10 +1262,6 @@ Module.prototype.load = function(filename) {
12701262 this . paths  =  Module . _nodeModulePaths ( path . dirname ( filename ) ) ; 
12711263
12721264 const  extension  =  findLongestRegisteredExtension ( filename ) ; 
1273-  // allow .mjs to be overridden 
1274-  if  ( StringPrototypeEndsWith ( filename ,  '.mjs' )  &&  ! Module . _extensions [ '.mjs' ] )  { 
1275-  throw  new  ERR_REQUIRE_ESM ( filename ,  true ) ; 
1276-  } 
12771265
12781266 Module . _extensions [ extension ] ( this ,  filename ) ; 
12791267 this . loaded  =  true ; 
@@ -1309,9 +1297,10 @@ let requireModuleWarningMode;
13091297 * Resolve and evaluate it synchronously as ESM if it's ESM. 
13101298 * @param  {Module } mod CJS module instance 
13111299 * @param  {string } filename Absolute path of the file. 
1300+  * @param  {string } format Format of the module. If it had types, this would be what it is after type-stripping. 
1301+  * @param  {string } source Source the module. If it had types, this would have the type stripped. 
13121302 */ 
1313- function  loadESMFromCJS ( mod ,  filename )  { 
1314-  const  source  =  getMaybeCachedSource ( mod ,  filename ) ; 
1303+ function  loadESMFromCJS ( mod ,  filename ,  format ,  source )  { 
13151304 const  cascadedLoader  =  require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ; 
13161305 const  isMain  =  mod [ kIsMainSymbol ] ; 
13171306 if  ( isMain )  { 
@@ -1487,7 +1476,9 @@ function wrapSafe(filename, content, cjsModuleInstance, format) {
14871476 * `exports`) to the file. Returns exception, if any. 
14881477 * @param  {string } content The source code of the module 
14891478 * @param  {string } filename The file path of the module 
1490-  * @param  {'module'|'commonjs'|undefined } format Intended format of the module. 
1479+  * @param  { 
1480+  * 'module'|'commonjs'|'commonjs-typescript'|'module-typescript' 
1481+  * } format Intended format of the module. 
14911482 */ 
14921483Module . prototype . _compile  =  function ( content ,  filename ,  format )  { 
14931484 let  moduleURL ; 
@@ -1509,9 +1500,7 @@ Module.prototype._compile = function(content, filename, format) {
15091500 } 
15101501
15111502 if  ( format  ===  'module' )  { 
1512-  // Pass the source into the .mjs extension handler indirectly through the cache. 
1513-  this [ kModuleSource ]  =  content ; 
1514-  loadESMFromCJS ( this ,  filename ) ; 
1503+  loadESMFromCJS ( this ,  filename ,  format ,  content ) ; 
15151504 return ; 
15161505 } 
15171506
@@ -1539,22 +1528,72 @@ Module.prototype._compile = function(content, filename, format) {
15391528
15401529/** 
15411530 * Get the source code of a module, using cached ones if it's cached. 
1531+  * After this returns, mod[kFormat], mod[kModuleSource] and mod[kURL] will be set. 
15421532 * @param  {Module } mod Module instance whose source is potentially already cached. 
15431533 * @param  {string } filename Absolute path to the file of the module. 
1544-  * @returns  {string } 
1534+  * @returns  {{source:  string, format?: string}  } 
15451535 */ 
1546- function  getMaybeCachedSource ( mod ,  filename )  { 
1547-  // If already analyzed the source, then it will be cached. 
1548-  let  content ; 
1549-  if  ( mod [ kModuleSource ]  !==  undefined )  { 
1550-  content  =  mod [ kModuleSource ] ; 
1536+ function  loadSource ( mod ,  filename ,  formatFromNode )  { 
1537+  if  ( formatFromNode  !==  undefined )  { 
1538+  mod [ kFormat ]  =  formatFromNode ; 
1539+  } 
1540+  const  format  =  mod [ kFormat ] ; 
1541+ 
1542+  let  source  =  mod [ kModuleSource ] ; 
1543+  if  ( source  !==  undefined )  { 
15511544 mod [ kModuleSource ]  =  undefined ; 
15521545 }  else  { 
15531546 // TODO(joyeecheung): we can read a buffer instead to speed up 
15541547 // compilation. 
1555-  content  =  fs . readFileSync ( filename ,  'utf8' ) ; 
1548+  source  =  fs . readFileSync ( filename ,  'utf8' ) ; 
1549+  } 
1550+  return  {  source,  format } ; 
1551+ } 
1552+ 
1553+ function  reconstructErrorStack ( err ,  parentPath ,  parentSource )  { 
1554+  const  errLine  =  StringPrototypeSplit ( 
1555+  StringPrototypeSlice ( err . stack ,  StringPrototypeIndexOf ( 
1556+  err . stack ,  ' at ' ) ) ,  '\n' ,  1 ) [ 0 ] ; 
1557+  const  {  1 : line ,  2 : col  }  = 
1558+  RegExpPrototypeExec ( / ( \d + ) : ( \d + ) \) / ,  errLine )  ||  [ ] ; 
1559+  if  ( line  &&  col )  { 
1560+  const  srcLine  =  StringPrototypeSplit ( parentSource ,  '\n' ) [ line  -  1 ] ; 
1561+  const  frame  =  `${ parentPath }  :${ line }  \n${ srcLine }  \n${ StringPrototypeRepeat ( ' ' ,  col  -  1 ) }  ^\n` ; 
1562+  setArrowMessage ( err ,  frame ) ; 
1563+  } 
1564+ } 
1565+ 
1566+ /** 
1567+  * Generate the legacy ERR_REQUIRE_ESM for the cases where require(esm) is disabled. 
1568+  * @param  {Module } mod The module being required. 
1569+  * @param  {undefined|object } pkg Data of the nearest package.json of the module. 
1570+  * @param  {string } content Source code of the module. 
1571+  * @param  {string } filename Filename of the module 
1572+  * @returns  {Error } 
1573+  */ 
1574+ function  getRequireESMError ( mod ,  pkg ,  content ,  filename )  { 
1575+  // This is an error path because `require` of a `.js` file in a `"type": "module"` scope is not allowed. 
1576+  const  parent  =  mod [ kModuleParent ] ; 
1577+  const  parentPath  =  parent ?. filename ; 
1578+  const  packageJsonPath  =  pkg ?. path  ? path . resolve ( pkg . path ,  'package.json' )  : null ; 
1579+  const  usesEsm  =  containsModuleSyntax ( content ,  filename ) ; 
1580+  const  err  =  new  ERR_REQUIRE_ESM ( filename ,  usesEsm ,  parentPath , 
1581+  packageJsonPath ) ; 
1582+  // Attempt to reconstruct the parent require frame. 
1583+  const  parentModule  =  Module . _cache [ parentPath ] ; 
1584+  if  ( parentModule )  { 
1585+  let  parentSource ; 
1586+  try  { 
1587+  ( {  source : parentSource  }  =  loadSource ( parentModule ,  parentPath ) ) ; 
1588+  }  catch  { 
1589+  // Continue regardless of error. 
1590+  } 
1591+  if  ( parentSource )  { 
1592+  // TODO(joyeecheung): trim off internal frames from the stack. 
1593+  reconstructErrorStack ( err ,  parentPath ,  parentSource ) ; 
1594+  } 
15561595 } 
1557-  return  content ; 
1596+  return  err ; 
15581597} 
15591598
15601599/** 
@@ -1563,57 +1602,25 @@ function getMaybeCachedSource(mod, filename) {
15631602 * @param  {string } filename The file path of the module 
15641603 */ 
15651604Module . _extensions [ '.js' ]  =  function ( module ,  filename )  { 
1566-  // If already analyzed the source, then it will be cached. 
1567-  const  content  =  getMaybeCachedSource ( module ,  filename ) ; 
1568- 
1569-  let  format ; 
1570-  if  ( StringPrototypeEndsWith ( filename ,  '.js' ) )  { 
1571-  const  pkg  =  packageJsonReader . readPackageScope ( filename )  ||  {  __proto__ : null  } ; 
1572-  // Function require shouldn't be used in ES modules. 
1573-  if  ( pkg . data ?. type  ===  'module' )  { 
1574-  if  ( getOptionValue ( '--experimental-require-module' ) )  { 
1575-  module . _compile ( content ,  filename ,  'module' ) ; 
1576-  return ; 
1577-  } 
1578- 
1579-  // This is an error path because `require` of a `.js` file in a `"type": "module"` scope is not allowed. 
1580-  const  parent  =  module [ kModuleParent ] ; 
1581-  const  parentPath  =  parent ?. filename ; 
1582-  const  packageJsonPath  =  path . resolve ( pkg . path ,  'package.json' ) ; 
1583-  const  usesEsm  =  containsModuleSyntax ( content ,  filename ) ; 
1584-  const  err  =  new  ERR_REQUIRE_ESM ( filename ,  usesEsm ,  parentPath , 
1585-  packageJsonPath ) ; 
1586-  // Attempt to reconstruct the parent require frame. 
1587-  if  ( Module . _cache [ parentPath ] )  { 
1588-  let  parentSource ; 
1589-  try  { 
1590-  parentSource  =  fs . readFileSync ( parentPath ,  'utf8' ) ; 
1591-  }  catch  { 
1592-  // Continue regardless of error. 
1593-  } 
1594-  if  ( parentSource )  { 
1595-  const  errLine  =  StringPrototypeSplit ( 
1596-  StringPrototypeSlice ( err . stack ,  StringPrototypeIndexOf ( 
1597-  err . stack ,  ' at ' ) ) ,  '\n' ,  1 ) [ 0 ] ; 
1598-  const  {  1 : line ,  2 : col  }  = 
1599-  RegExpPrototypeExec ( / ( \d + ) : ( \d + ) \) / ,  errLine )  ||  [ ] ; 
1600-  if  ( line  &&  col )  { 
1601-  const  srcLine  =  StringPrototypeSplit ( parentSource ,  '\n' ) [ line  -  1 ] ; 
1602-  const  frame  =  `${ parentPath }  :${ line }  \n${ srcLine }  \n${  
1603-  StringPrototypeRepeat ( ' ' ,  col  -  1 ) }  ^\n`; 
1604-  setArrowMessage ( err ,  frame ) ; 
1605-  } 
1606-  } 
1607-  } 
1608-  throw  err ; 
1609-  }  else  if  ( pkg . data ?. type  ===  'commonjs' )  { 
1610-  format  =  'commonjs' ; 
1611-  } 
1612-  }  else  if  ( StringPrototypeEndsWith ( filename ,  '.cjs' ) )  { 
1605+  let  format ,  pkg ; 
1606+  if  ( StringPrototypeEndsWith ( filename ,  '.cjs' ) )  { 
16131607 format  =  'commonjs' ; 
1608+  }  else  if  ( StringPrototypeEndsWith ( filename ,  '.mjs' ) )  { 
1609+  format  =  'module' ; 
1610+  }  else  if  ( StringPrototypeEndsWith ( filename ,  '.js' ) )  { 
1611+  pkg  =  packageJsonReader . readPackageScope ( filename )  ||  {  __proto__ : null  } ; 
1612+  const  typeFromPjson  =  pkg . data ?. type ; 
1613+  if  ( typeFromPjson  ===  'module'  ||  typeFromPjson  ===  'commonjs'  ||  ! typeFromPjson )  { 
1614+  format  =  typeFromPjson ; 
1615+  } 
16141616 } 
1615- 
1616-  module . _compile ( content ,  filename ,  format ) ; 
1617+  const  {  source,  format : loadedFormat  }  =  loadSource ( module ,  filename ,  format ) ; 
1618+  // Function require shouldn't be used in ES modules when require(esm) is disabled. 
1619+  if  ( loadedFormat  ===  'module'  &&  ! getOptionValue ( '--experimental-require-module' ) )  { 
1620+  const  err  =  getRequireESMError ( module ,  pkg ,  source ,  filename ) ; 
1621+  throw  err ; 
1622+  } 
1623+  module . _compile ( source ,  filename ,  loadedFormat ) ; 
16171624} ; 
16181625
16191626/** 
0 commit comments