module: clarify cjs global-like error on ModuleJobSync

PR-URL: https://github.com/nodejs/node/pull/56491
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
This commit is contained in:
Carlos Espa 2025-05-16 08:39:28 +02:00 committed by GitHub
parent 0c78a48d75
commit b6189c352c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 40 additions and 24 deletions

View File

@ -65,6 +65,37 @@ const isCommonJSGlobalLikeNotDefinedError = (errorMessage) =>
(globalLike) => errorMessage === `${globalLike} is not defined`,
);
/**
*
* @param {Error} e
* @param {string} url
* @returns {void}
*/
const explainCommonJSGlobalLikeNotDefinedError = (e, url) => {
if (e?.name === 'ReferenceError' &&
isCommonJSGlobalLikeNotDefinedError(e.message)) {
e.message += ' in ES module scope';
if (StringPrototypeStartsWith(e.message, 'require ')) {
e.message += ', you can use import instead';
}
const packageConfig =
StringPrototypeStartsWith(url, 'file://') &&
RegExpPrototypeExec(/\.js(\?[^#]*)?(#.*)?$/, url) !== null &&
require('internal/modules/package_json_reader')
.getPackageScopeConfig(url);
if (packageConfig.type === 'module') {
e.message +=
'\nThis file is being treated as an ES module because it has a ' +
`'.js' file extension and '${packageConfig.pjsonPath}' contains ` +
'"type": "module". To treat it as a CommonJS script, rename it ' +
'to use the \'.cjs\' file extension.';
}
}
};
class ModuleJobBase {
constructor(url, importAttributes, phase, isMain, inspectBrk) {
assert(typeof phase === 'number');
@ -326,27 +357,7 @@ class ModuleJob extends ModuleJobBase {
try {
await this.module.evaluate(timeout, breakOnSigint);
} catch (e) {
if (e?.name === 'ReferenceError' &&
isCommonJSGlobalLikeNotDefinedError(e.message)) {
e.message += ' in ES module scope';
if (StringPrototypeStartsWith(e.message, 'require ')) {
e.message += ', you can use import instead';
}
const packageConfig =
StringPrototypeStartsWith(this.module.url, 'file://') &&
RegExpPrototypeExec(/\.js(\?[^#]*)?(#.*)?$/, this.module.url) !== null &&
require('internal/modules/package_json_reader')
.getPackageScopeConfig(this.module.url);
if (packageConfig.type === 'module') {
e.message +=
'\nThis file is being treated as an ES module because it has a ' +
`'.js' file extension and '${packageConfig.pjsonPath}' contains ` +
'"type": "module". To treat it as a CommonJS script, rename it ' +
'to use the \'.cjs\' file extension.';
}
}
explainCommonJSGlobalLikeNotDefinedError(e, this.module.url);
throw e;
}
return { __proto__: null, module: this.module };
@ -476,8 +487,13 @@ class ModuleJobSync extends ModuleJobBase {
throw new ERR_REQUIRE_ASYNC_MODULE(filename, parentFilename);
}
setHasStartedUserESMExecution();
const namespace = this.module.evaluateSync(filename, parentFilename);
return { __proto__: null, module: this.module, namespace };
try {
const namespace = this.module.evaluateSync(filename, parentFilename);
return { __proto__: null, module: this.module, namespace };
} catch (e) {
explainCommonJSGlobalLikeNotDefinedError(e, this.module.url);
throw e;
}
}
}

View File

@ -17,5 +17,5 @@ assert.throws(() => {
require('../fixtures/es-modules/reference-error-esm.js');
}, {
name: 'ReferenceError',
message: 'exports is not defined'
message: 'exports is not defined in ES module scope'
});