node/test/es-module/test-esm-cjs-named-error.mjs

78 lines
2.5 KiB
JavaScript
Raw Normal View History

import '../common/index.mjs';
import { rejects } from 'assert';
const fixtureBase = '../fixtures/es-modules/package-cjs-named-error';
const errTemplate = (specifier, name, namedImports) =>
`Named export '${name}' not found. The requested module` +
` '${specifier}' is a CommonJS module, which may not support ` +
'all module.exports as named exports.\nCommonJS modules can ' +
'always be imported via the default export, for example using:' +
`\n\nimport pkg from '${specifier}';\n` + (namedImports ?
`const ${namedImports} = pkg;\n` : '');
const expectedWithoutExample = errTemplate('./fail.cjs', 'comeOn');
const expectedRelative = errTemplate('./fail.cjs', 'comeOn', '{ comeOn }');
const expectedRenamed = errTemplate('./fail.cjs', 'comeOn',
'{ comeOn: comeOnRenamed }');
const expectedPackageHack =
errTemplate('./json-hack/fail.js', 'comeOn', '{ comeOn }');
const expectedBare = errTemplate('deep-fail', 'comeOn', '{ comeOn }');
await rejects(async () => {
await import(`${fixtureBase}/single-quote.mjs`);
}, {
name: 'SyntaxError',
message: expectedRelative
}, 'should support relative specifiers with single quotes');
await rejects(async () => {
await import(`${fixtureBase}/double-quote.mjs`);
}, {
name: 'SyntaxError',
message: expectedRelative
}, 'should support relative specifiers with double quotes');
await rejects(async () => {
await import(`${fixtureBase}/renamed-import.mjs`);
}, {
name: 'SyntaxError',
message: expectedRenamed
}, 'should correctly format named imports with renames');
await rejects(async () => {
module: fix crash on multiline named cjs imports The node process crashes when trying to parse a multiline import statement for named exports of a CommonJS module: TypeError: Cannot read property '0' of null at ModuleJob._instantiate (internal/modules/esm/module_job.js:112:77) at async ModuleJob.run (internal/modules/esm/module_job.js:137:5) at async Loader.import (internal/modules/esm/loader.js:165:24) at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3) at async waitForActual (assert.js:721:5) at async rejects (assert.js:830:25), The reason is that the regexp that is currently used to decorate the original error fails for multi line import statements. Unfortunately the undecorated error stack only contains the single line which causes the import to fail: file:///***/node/test/fixtures/es-modules/package-cjs-named-error/multi-line.mjs:2 comeOn, ^^^^^^ SyntaxError: The requested module './fail.cjs' does not provide an export named 'comeOn' at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21) at async ModuleJob.run (internal/modules/esm/module_job.js:141:5) at async Loader.import (internal/modules/esm/loader.js:165:24) at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3) at async waitForActual (assert.js:721:5) at async rejects (assert.js:830:25) Hence, for multiline import statements we cannot create an equivalent piece of code that uses default import followed by an object destructuring assignment. In any case the node process should definitely not crash. So until we have a more sophisticated way of extracting the entire problematic multiline import statement, show the code example only for single-line imports where the current regexp approach works well. Refs: https://github.com/nodejs/node/issues/35259 PR-URL: https://github.com/nodejs/node/pull/35275 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
2020-09-18 22:35:34 +08:00
await import(`${fixtureBase}/multi-line.mjs`);
}, {
name: 'SyntaxError',
message: expectedWithoutExample,
}, 'should correctly format named imports across multiple lines');
await rejects(async () => {
await import(`${fixtureBase}/json-hack.mjs`);
}, {
name: 'SyntaxError',
message: expectedPackageHack
}, 'should respect recursive package.json for module type');
await rejects(async () => {
await import(`${fixtureBase}/bare-import-single.mjs`);
}, {
name: 'SyntaxError',
message: expectedBare
}, 'should support bare specifiers with single quotes');
await rejects(async () => {
await import(`${fixtureBase}/bare-import-double.mjs`);
}, {
name: 'SyntaxError',
message: expectedBare
}, 'should support bare specifiers with double quotes');
await rejects(async () => {
await import(`${fixtureBase}/escaped-single-quote.mjs`);
}, /import pkg from '\.\/oh'no\.cjs'/, 'should support relative specifiers with escaped single quote');