Skip to content

Commit ed43b69

Browse files
Ceres6marco-ippolito
authored andcommitted
module: clarify cjs global-like error on ModuleJobSync
PR-URL: #56491 Backport-PR-URL: #59504 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Jacob Smith <jacob@frende.me> Refs: #52697
1 parent 6e02db1 commit ed43b69

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

lib/internal/modules/esm/module_job.js

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,37 @@ const isCommonJSGlobalLikeNotDefinedError = (errorMessage) =>
5858
(globalLike) => errorMessage === `${globalLike} is not defined`,
5959
);
6060

61+
62+
/**
63+
*
64+
* @param {Error} e
65+
* @param {string} url
66+
* @returns {void}
67+
*/
68+
const explainCommonJSGlobalLikeNotDefinedError = (e, url) => {
69+
if (e?.name === 'ReferenceError' &&
70+
isCommonJSGlobalLikeNotDefinedError(e.message)) {
71+
e.message += ' in ES module scope';
72+
73+
if (StringPrototypeStartsWith(e.message, 'require ')) {
74+
e.message += ', you can use import instead';
75+
}
76+
77+
const packageConfig =
78+
StringPrototypeStartsWith(url, 'file://') &&
79+
RegExpPrototypeExec(/\.js(\?[^#]*)?(#.*)?$/, url) !== null &&
80+
require('internal/modules/esm/resolve')
81+
.getPackageScopeConfig(url);
82+
if (packageConfig.type === 'module') {
83+
e.message +=
84+
'\nThis file is being treated as an ES module because it has a ' +
85+
`'.js' file extension and '${packageConfig.pjsonPath}' contains ` +
86+
'"type": "module". To treat it as a CommonJS script, rename it ' +
87+
'to use the \'.cjs\' file extension.';
88+
}
89+
}
90+
};
91+
6192
class ModuleJobBase {
6293
constructor(url, importAttributes, isMain, inspectBrk) {
6394
this.importAttributes = importAttributes;
@@ -285,27 +316,7 @@ class ModuleJob extends ModuleJobBase {
285316
try {
286317
await this.module.evaluate(timeout, breakOnSigint);
287318
} catch (e) {
288-
if (e?.name === 'ReferenceError' &&
289-
isCommonJSGlobalLikeNotDefinedError(e.message)) {
290-
e.message += ' in ES module scope';
291-
292-
if (StringPrototypeStartsWith(e.message, 'require ')) {
293-
e.message += ', you can use import instead';
294-
}
295-
296-
const packageConfig =
297-
StringPrototypeStartsWith(this.module.url, 'file://') &&
298-
RegExpPrototypeExec(/\.js(\?[^#]*)?(#.*)?$/, this.module.url) !== null &&
299-
require('internal/modules/esm/resolve')
300-
.getPackageScopeConfig(this.module.url);
301-
if (packageConfig.type === 'module') {
302-
e.message +=
303-
'\nThis file is being treated as an ES module because it has a ' +
304-
`'.js' file extension and '${packageConfig.pjsonPath}' contains ` +
305-
'"type": "module". To treat it as a CommonJS script, rename it ' +
306-
'to use the \'.cjs\' file extension.';
307-
}
308-
}
319+
explainCommonJSGlobalLikeNotDefinedError(e, this.module.url);
309320
throw e;
310321
}
311322
return { __proto__: null, module: this.module };
@@ -409,8 +420,13 @@ class ModuleJobSync extends ModuleJobBase {
409420
throw new ERR_REQUIRE_ASYNC_MODULE(filename, parentFilename);
410421
}
411422
setHasStartedUserESMExecution();
412-
const namespace = this.module.evaluateSync(filename, parentFilename);
413-
return { __proto__: null, module: this.module, namespace };
423+
try {
424+
const namespace = this.module.evaluateSync(filename, parentFilename);
425+
return { __proto__: null, module: this.module, namespace };
426+
} catch (e) {
427+
explainCommonJSGlobalLikeNotDefinedError(e, this.module.url);
428+
throw e;
429+
}
414430
}
415431
}
416432

test/es-module/test-require-module-error-catching.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ assert.throws(() => {
1717
require('../fixtures/es-modules/reference-error-esm.js');
1818
}, {
1919
name: 'ReferenceError',
20-
message: 'exports is not defined'
20+
message: 'exports is not defined in ES module scope'
2121
});

0 commit comments

Comments
 (0)