99 ObjectKeys,
1010 PromisePrototypeCatch,
1111 PromiseReject,
12+ RegExpPrototypeTest,
1213 SafeMap,
1314 SafeSet,
1415 StringPrototypeReplace,
16+ StringPrototypeSplit,
17+ StringPrototypeStartsWith,
1518} = primordials ;
1619
1720let _TYPES = null ;
@@ -54,9 +57,11 @@ const experimentalImportMetaResolve =
5457 getOptionValue ( '--experimental-import-meta-resolve' ) ;
5558const asyncESM = require ( 'internal/process/esm_loader' ) ;
5659const cjsParse = require ( 'internal/deps/cjs-module-lexer/lexer' ) ;
60+ const { emitWarningSync } = require ( 'internal/process/warning' ) ;
5761
5862const translators = new SafeMap ( ) ;
5963exports . translators = translators ;
64+ exports . enrichCJSError = enrichCJSError ;
6065
6166let DECODER = null ;
6267function assertBufferSource ( body , allowString , hookName ) {
@@ -130,6 +135,25 @@ translators.set('module', async function moduleStrategy(url) {
130135 return module ;
131136} ) ;
132137
138+ function enrichCJSError ( err ) {
139+ const stack = StringPrototypeSplit ( err . stack , '\n' ) ;
140+ /*
141+ * The regular expression below targets the most common import statement
142+ * usage. However, some cases are not matching, cases like import statement
143+ * after a comment block and/or after a variable definition.
144+ */
145+ if ( StringPrototypeStartsWith ( err . message , 'Unexpected token \'export\'' ) ||
146+ RegExpPrototypeTest ( / ^ \s * i m p o r t (? = [ { ' " * ] ) \s * (? ! [ ( ] ) / , stack [ 1 ] ) ) {
147+ // Emit the warning synchronously because we are in the middle of handling
148+ // a SyntaxError that will throw and likely terminate the process before an
149+ // asynchronous warning would be emitted.
150+ emitWarningSync (
151+ 'To load an ES module, set "type": "module" in the package.json or use ' +
152+ 'the .mjs extension.'
153+ ) ;
154+ }
155+ }
156+
133157// Strategy for loading a node-style CommonJS module
134158const isWindows = process . platform === 'win32' ;
135159const winSepRegEx = / \/ / g;
@@ -152,7 +176,12 @@ translators.set('commonjs', async function commonjsStrategy(url, isMain) {
152176 exports = asyncESM . ESMLoader . cjsCache . get ( module ) ;
153177 asyncESM . ESMLoader . cjsCache . delete ( module ) ;
154178 } else {
155- exports = CJSModule . _load ( filename , undefined , isMain ) ;
179+ try {
180+ exports = CJSModule . _load ( filename , undefined , isMain ) ;
181+ } catch ( err ) {
182+ enrichCJSError ( err ) ;
183+ throw err ;
184+ }
156185 }
157186
158187 for ( const exportName of exportNames ) {
@@ -190,7 +219,13 @@ function cjsPreparseModuleExports(filename) {
190219 source = readFileSync ( filename , 'utf8' ) ;
191220 } catch { }
192221
193- const { exports, reexports } = cjsParse ( source || '' ) ;
222+ let exports , reexports ;
223+ try {
224+ ( { exports, reexports } = cjsParse ( source || '' ) ) ;
225+ } catch {
226+ exports = [ ] ;
227+ reexports = [ ] ;
228+ }
194229
195230 const exportNames = new SafeSet ( exports ) ;
196231
0 commit comments