9
9
ObjectKeys,
10
10
PromisePrototypeCatch,
11
11
PromiseReject,
12
+ RegExpPrototypeTest,
12
13
SafeMap,
13
14
SafeSet,
14
15
StringPrototypeReplace,
16
+ StringPrototypeSplit,
17
+ StringPrototypeStartsWith,
15
18
} = primordials ;
16
19
17
20
let _TYPES = null ;
@@ -57,6 +60,7 @@ const cjsParse = require('internal/deps/cjs-module-lexer/lexer');
57
60
58
61
const translators = new SafeMap ( ) ;
59
62
exports . translators = translators ;
63
+ exports . enrichCJSError = enrichCJSError ;
60
64
61
65
let DECODER = null ;
62
66
function assertBufferSource ( body , allowString , hookName ) {
@@ -130,6 +134,29 @@ translators.set('module', async function moduleStrategy(url) {
130
134
return module ;
131
135
} ) ;
132
136
137
+
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
+ process . emitWarning (
151
+ 'To load an ES module, set "type": "module" in the package.json or use ' +
152
+ 'the .mjs extension.' ,
153
+ undefined ,
154
+ undefined ,
155
+ undefined ,
156
+ true ) ;
157
+ }
158
+ }
159
+
133
160
// Strategy for loading a node-style CommonJS module
134
161
const isWindows = process . platform === 'win32' ;
135
162
const winSepRegEx = / \/ / g;
@@ -152,7 +179,12 @@ translators.set('commonjs', async function commonjsStrategy(url, isMain) {
152
179
exports = asyncESM . ESMLoader . cjsCache . get ( module ) ;
153
180
asyncESM . ESMLoader . cjsCache . delete ( module ) ;
154
181
} else {
155
- exports = CJSModule . _load ( filename , undefined , isMain ) ;
182
+ try {
183
+ exports = CJSModule . _load ( filename , undefined , isMain ) ;
184
+ } catch ( err ) {
185
+ enrichCJSError ( err ) ;
186
+ throw err ;
187
+ }
156
188
}
157
189
158
190
for ( const exportName of exportNames ) {
@@ -190,7 +222,13 @@ function cjsPreparseModuleExports(filename) {
190
222
source = readFileSync ( filename , 'utf8' ) ;
191
223
} catch { }
192
224
193
- const { exports, reexports } = cjsParse ( source || '' ) ;
225
+ let exports , reexports ;
226
+ try {
227
+ ( { exports, reexports } = cjsParse ( source || '' ) ) ;
228
+ } catch {
229
+ exports = [ ] ;
230
+ reexports = [ ] ;
231
+ }
194
232
195
233
const exportNames = new SafeSet ( exports ) ;
196
234
0 commit comments