@@ -4,17 +4,20 @@ const {
44 ArrayPrototypeJoin,
55 ArrayPrototypeMap,
66 ArrayPrototypePush,
7+ ArrayPrototypeSome,
78 FunctionPrototype,
89 ObjectSetPrototypeOf,
910 PromiseAll,
1011 PromiseResolve,
1112 PromisePrototypeCatch,
1213 ReflectApply,
14+ RegExpPrototypeTest,
1315 SafeSet,
1416 StringPrototypeIncludes,
1517 StringPrototypeMatch,
1618 StringPrototypeReplace,
1719 StringPrototypeSplit,
20+ StringPrototypeStartsWith,
1821} = primordials ;
1922
2023const { ModuleWrap } = internalBinding ( 'module_wrap' ) ;
@@ -27,6 +30,19 @@ const noop = FunctionPrototype;
2730
2831let hasPausedEntry = false ;
2932
33+ const CJSGlobalLike = [
34+ 'require' ,
35+ 'module' ,
36+ 'exports' ,
37+ '__filename' ,
38+ '__dirname' ,
39+ ] ;
40+ const isCommonJSGlobalLikeNotDefinedError = ( errorMessage ) =>
41+ ArrayPrototypeSome (
42+ CJSGlobalLike ,
43+ ( globalLike ) => errorMessage === `${ globalLike } is not defined`
44+ ) ;
45+
3046/* A ModuleJob tracks the loading of a single Module, and the ModuleJobs of
3147 * its dependencies, over time. */
3248class ModuleJob {
@@ -149,7 +165,32 @@ class ModuleJob {
149165 await this . instantiate ( ) ;
150166 const timeout = - 1 ;
151167 const breakOnSigint = false ;
152- await this . module . evaluate ( timeout , breakOnSigint ) ;
168+ try {
169+ await this . module . evaluate ( timeout , breakOnSigint ) ;
170+ } catch ( e ) {
171+ if ( e ?. name === 'ReferenceError' &&
172+ isCommonJSGlobalLikeNotDefinedError ( e . message ) ) {
173+ e . message += ' in ES module scope' ;
174+
175+ if ( StringPrototypeStartsWith ( e . message , 'require ' ) ) {
176+ e . message += ', you can use import instead' ;
177+ }
178+
179+ const packageConfig =
180+ StringPrototypeStartsWith ( this . module . url , 'file://' ) &&
181+ RegExpPrototypeTest ( / \. j s ( \? [ ^ # ] * ) ? ( # .* ) ? $ / , this . module . url ) &&
182+ require ( 'internal/modules/esm/resolve' )
183+ . getPackageScopeConfig ( this . module . url ) ;
184+ if ( packageConfig . type === 'module' ) {
185+ e . message +=
186+ '\nThis file is being treated as an ES module because it has a ' +
187+ `'.js' file extension and '${ packageConfig . pjsonPath } ' contains ` +
188+ '"type": "module". To treat it as a CommonJS script, rename it ' +
189+ 'to use the \'.cjs\' file extension.' ;
190+ }
191+ }
192+ throw e ;
193+ }
153194 return { module : this . module } ;
154195 }
155196}
0 commit comments