@@ -21,6 +21,7 @@ const experimentalNetworkImports =
2121const defaultTypeFlag = getOptionValue ( '--experimental-default-type' ) ;
2222// The next line is where we flip the default to ES modules someday.
2323const defaultType = defaultTypeFlag === 'module' ? 'module' : 'commonjs' ;
24+ const { containsModuleSyntax } = internalBinding ( 'contextify' ) ;
2425const { getPackageType } = require ( 'internal/modules/esm/resolve' ) ;
2526const { fileURLToPath } = require ( 'internal/url' ) ;
2627const { ERR_UNKNOWN_FILE_EXTENSION } = require ( 'internal/errors' ) . codes ;
@@ -85,42 +86,66 @@ function underNodeModules(url) {
8586
8687/**
8788 * @param {URL } url
88- * @param {{parentURL: string} } context
89+ * @param {{parentURL: string; source?: Buffer } } context
8990 * @param {boolean } ignoreErrors
9091 * @returns {string }
9192 */
92- function getFileProtocolModuleFormat ( url , context , ignoreErrors ) {
93+ function getFileProtocolModuleFormat ( url , context = { __proto__ : null } , ignoreErrors ) {
94+ const { source } = context ;
9395 const ext = extname ( url ) ;
9496
9597 if ( ext === '.js' ) {
9698 const packageType = getPackageType ( url ) ;
9799 if ( packageType !== 'none' ) {
98100 return packageType ;
99101 }
102+
100103 // The controlling `package.json` file has no `type` field.
101- if ( defaultType === 'module' ) {
102- // An exception to the type flag making ESM the default everywhere is that package scopes under `node_modules`
103- // should retain the assumption that a lack of a `type` field means CommonJS.
104- return underNodeModules ( url ) ? 'commonjs' : 'module' ;
104+ switch ( getOptionValue ( '--experimental-default-type' ) ) {
105+ case 'module' : { // The user explicitly passed `--experimental-default-type=module`.
106+ // An exception to the type flag making ESM the default everywhere is that package scopes under `node_modules`
107+ // should retain the assumption that a lack of a `type` field means CommonJS.
108+ return underNodeModules ( url ) ? 'commonjs' : 'module' ;
109+ }
110+ case 'commonjs' : { // The user explicitly passed `--experimental-default-type=commonjs`.
111+ return 'commonjs' ;
112+ }
113+ default : { // The user did not pass `--experimental-default-type`.
114+ // `source` is undefined when this is called from `defaultResolve`;
115+ // but this gets called again from `defaultLoad`/`defaultLoadSync`.
116+ if ( source && getOptionValue ( '--experimental-detect-module' ) ) {
117+ return containsModuleSyntax ( `${ source } ` , fileURLToPath ( url ) ) ? 'module' : 'commonjs' ;
118+ }
119+ return 'commonjs' ;
120+ }
105121 }
106- return 'commonjs' ;
107122 }
108123
109124 if ( ext === '' ) {
110125 const packageType = getPackageType ( url ) ;
111- if ( defaultType === 'commonjs' ) { // Legacy behavior
112- if ( packageType === 'none' || packageType === 'commonjs' ) {
113- return 'commonjs' ;
114- } // Else packageType === 'module'
126+ if ( packageType === 'module' ) {
115127 return getFormatOfExtensionlessFile ( url ) ;
116- } // Else defaultType === 'module'
117- if ( underNodeModules ( url ) ) { // Exception for package scopes under `node_modules`
118- return packageType === 'module' ? getFormatOfExtensionlessFile ( url ) : 'commonjs' ;
119128 }
120- if ( packageType === 'none' || packageType === 'module' ) {
121- return getFormatOfExtensionlessFile ( url ) ;
122- } // Else packageType === 'commonjs'
123- return 'commonjs' ;
129+ if ( packageType !== 'none' ) {
130+ return packageType ; // 'commonjs' or future package types
131+ }
132+
133+ // The controlling `package.json` file has no `type` field.
134+ switch ( getOptionValue ( '--experimental-default-type' ) ) {
135+ case 'module' : { // The user explicitly passed `--experimental-default-type=module`.
136+ return underNodeModules ( url ) ? 'commonjs' : getFormatOfExtensionlessFile ( url ) ;
137+ }
138+ case 'commonjs' : { // The user explicitly passed `--experimental-default-type=commonjs`.
139+ return 'commonjs' ;
140+ }
141+ default : { // The user did not pass `--experimental-default-type`.
142+ if ( source && getOptionValue ( '--experimental-detect-module' ) &&
143+ getFormatOfExtensionlessFile ( url ) === 'module' ) {
144+ return containsModuleSyntax ( `${ source } ` , fileURLToPath ( url ) ) ? 'module' : 'commonjs' ;
145+ }
146+ return 'commonjs' ;
147+ }
148+ }
124149 }
125150
126151 const format = extensionFormatMap [ ext ] ;
0 commit comments