1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

fix(node): improve error message requiring non-npm es module (#19856)

Closes #19842
Closes #16913
This commit is contained in:
David Sherret 2023-07-17 16:19:00 -04:00 committed by GitHub
parent 7a9f7f3419
commit 4ebe3bdb06
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 29 deletions

View file

@ -104,6 +104,14 @@ itest!(cjs_require_esm_mjs_error {
exit_code: 1, exit_code: 1,
}); });
itest!(require_esm_error {
args: "run --allow-read --quiet node/require_esm_error/main.ts",
output: "node/require_esm_error/main.out",
envs: env_vars_for_npm_tests(),
http_server: true,
exit_code: 1,
});
itest!(translate_cjs_to_esm { itest!(translate_cjs_to_esm {
args: "run -A --quiet npm/translate_cjs_to_esm/main.js", args: "run -A --quiet npm/translate_cjs_to_esm/main.js",
output: "npm/translate_cjs_to_esm/main.out", output: "npm/translate_cjs_to_esm/main.out",

View file

@ -0,0 +1 @@
export class Test {}

View file

@ -0,0 +1,3 @@
error: Uncaught Error: require() of ES Module [WILDCARD]esm.js from [WILDCARD]main.ts not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
at [WILDCARD]
at file:///[WILDCARD]/require_esm_error/main.ts:5:1

View file

@ -0,0 +1,5 @@
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
require("./esm.js");

View file

@ -1,4 +1,2 @@
error: Uncaught Error: [ERR_REQUIRE_ESM]: require() of ES Module [WILDCARD]my_esm_module.js from [WILDCARD]index.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules. error: Uncaught Error: require() of ES Module [WILDCARD]my_esm_module.js from [WILDCARD]index.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
at Object.Module._extensions..js (node:module:[WILDCARD])
[WILDCARD] [WILDCARD]
at Module.load (node:module:[WILDCARD])

View file

@ -1,4 +1,2 @@
error: Uncaught Error: [ERR_REQUIRE_ESM]: require() of ES Module [WILDCARD]esm_mjs.mjs from [WILDCARD]require_mjs.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules. error: Uncaught Error: require() of ES Module [WILDCARD]esm_mjs.mjs from [WILDCARD]require_mjs.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
at Module.load (node:module:[WILDCARD])
[WILDCARD] [WILDCARD]
at Function.Module._load (node:module:[WILDCARD])

View file

@ -878,9 +878,9 @@ Module.prototype.load = function (filename) {
if ( if (
StringPrototypeEndsWith(filename, ".mjs") && !Module._extensions[".mjs"] StringPrototypeEndsWith(filename, ".mjs") && !Module._extensions[".mjs"]
) { ) {
// TODO: use proper error class throw createRequireEsmError(
throw new Error( filename,
requireEsmErrorText(filename, moduleParentCache.get(this)?.filename), moduleParentCache.get(this)?.filename,
); );
} }
@ -923,22 +923,24 @@ Module.wrap = function (script) {
return `${Module.wrapper[0]}${script}${Module.wrapper[1]}`; return `${Module.wrapper[0]}${script}${Module.wrapper[1]}`;
}; };
function enrichCJSError(error) { function isEsmSyntaxError(error) {
if (error instanceof SyntaxError) { return error instanceof SyntaxError && (
if (
StringPrototypeIncludes( StringPrototypeIncludes(
error.message, error.message,
"Cannot use import statement outside a module", "Cannot use import statement outside a module",
) || ) ||
StringPrototypeIncludes(error.message, "Unexpected token 'export'") StringPrototypeIncludes(error.message, "Unexpected token 'export'")
) { );
}
function enrichCJSError(error) {
if (isEsmSyntaxError(error)) {
console.error( console.error(
'To load an ES module, set "type": "module" in the package.json or use ' + 'To load an ES module, set "type": "module" in the package.json or use ' +
"the .mjs extension.", "the .mjs extension.",
); );
} }
} }
}
function wrapSafe( function wrapSafe(
filename, filename,
@ -951,8 +953,15 @@ function wrapSafe(
if (nodeGlobalThis.process.mainModule === cjsModuleInstance) { if (nodeGlobalThis.process.mainModule === cjsModuleInstance) {
enrichCJSError(err.thrown); enrichCJSError(err.thrown);
} }
if (isEsmSyntaxError(err.thrown)) {
throw createRequireEsmError(
filename,
moduleParentCache.get(cjsModuleInstance)?.filename,
);
} else {
throw err.thrown; throw err.thrown;
} }
}
return f; return f;
} }
@ -963,7 +972,6 @@ Module.prototype._compile = function (content, filename) {
const require = makeRequireFunction(this); const require = makeRequireFunction(this);
const exports = this.exports; const exports = this.exports;
const thisValue = exports; const thisValue = exports;
const module = this;
if (requireDepth === 0) { if (requireDepth === 0) {
statCache = new SafeMap(); statCache = new SafeMap();
} }
@ -994,8 +1002,9 @@ Module._extensions[".js"] = function (module, filename) {
if (StringPrototypeEndsWith(filename, ".js")) { if (StringPrototypeEndsWith(filename, ".js")) {
const pkg = ops.op_require_read_closest_package_json(filename); const pkg = ops.op_require_read_closest_package_json(filename);
if (pkg && pkg.exists && pkg.typ === "module") { if (pkg && pkg.exists && pkg.typ === "module") {
throw new Error( throw createRequireEsmError(
requireEsmErrorText(filename, moduleParentCache.get(module)?.filename), filename,
moduleParentCache.get(module)?.filename,
); );
} }
} }
@ -1003,8 +1012,8 @@ Module._extensions[".js"] = function (module, filename) {
module._compile(content, filename); module._compile(content, filename);
}; };
function requireEsmErrorText(filename, parent) { function createRequireEsmError(filename, parent) {
let message = `[ERR_REQUIRE_ESM]: require() of ES Module ${filename}`; let message = `require() of ES Module ${filename}`;
if (parent) { if (parent) {
message += ` from ${parent}`; message += ` from ${parent}`;
@ -1012,7 +1021,9 @@ function requireEsmErrorText(filename, parent) {
message += message +=
` not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.`; ` not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.`;
return message; const err = new Error(message);
err.code = "ERR_REQUIRE_ESM";
return err;
} }
function stripBOM(content) { function stripBOM(content) {