diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index b00a4fb2a58a7f..4ffa8db9dab903 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -8,6 +8,7 @@ const { SafePromise, StringPrototypeIncludes, StringPrototypeMatch, + StringPrototypeReplace, StringPrototypeSplit, } = primordials; @@ -109,13 +110,14 @@ class ModuleJob { if (format === 'commonjs') { const importStatement = splitStack[1]; const namedImports = StringPrototypeMatch(importStatement, /{.*}/)[0]; + const destructuringAssignment = StringPrototypeReplace(namedImports, /\s+as\s+/g, ': '); e.message = `The requested module '${childSpecifier}' is expected ` + 'to be of type CommonJS, which does not support named exports. ' + 'CommonJS modules can be imported by importing the default ' + 'export.\n' + 'For example:\n' + `import pkg from '${childSpecifier}';\n` + - `const ${namedImports} = pkg;`; + `const ${destructuringAssignment} = pkg;`; const newStack = StringPrototypeSplit(e.stack, '\n'); newStack[3] = `SyntaxError: ${e.message}`; e.stack = ArrayPrototypeJoin(newStack, '\n'); diff --git a/test/es-module/test-esm-cjs-named-error.mjs b/test/es-module/test-esm-cjs-named-error.mjs index d34f762dfb4e26..d71dc959e21fb7 100644 --- a/test/es-module/test-esm-cjs-named-error.mjs +++ b/test/es-module/test-esm-cjs-named-error.mjs @@ -10,6 +10,13 @@ const expectedRelative = 'The requested module \'./fail.cjs\' is expected to ' + 'import pkg from \'./fail.cjs\';\n' + 'const { comeOn } = pkg;'; +const expectedRenamed = 'The requested module \'./fail.cjs\' is expected to ' + + 'be of type CommonJS, which does not support named exports. CommonJS ' + + 'modules can be imported by importing the default export.\n' + + 'For example:\n' + + 'import pkg from \'./fail.cjs\';\n' + + 'const { comeOn: comeOnRenamed } = pkg;'; + const expectedPackageHack = 'The requested module \'./json-hack/fail.js\' is ' + 'expected to be of type CommonJS, which does not support named exports. ' + 'CommonJS modules can be imported by importing the default export.\n' + @@ -38,6 +45,13 @@ rejects(async () => { message: expectedRelative }, 'should support relative specifiers with double quotes'); +rejects(async () => { + await import(`${fixtureBase}/renamed-import.mjs`); +}, { + name: 'SyntaxError', + message: expectedRenamed +}, 'should correctly format named imports with renames'); + rejects(async () => { await import(`${fixtureBase}/json-hack.mjs`); }, { diff --git a/test/fixtures/es-modules/package-cjs-named-error/renamed-import.mjs b/test/fixtures/es-modules/package-cjs-named-error/renamed-import.mjs new file mode 100644 index 00000000000000..dc601f28fe2f99 --- /dev/null +++ b/test/fixtures/es-modules/package-cjs-named-error/renamed-import.mjs @@ -0,0 +1 @@ +import { comeOn as comeOnRenamed } from "./fail.cjs"