GeezerVison is showing github.com — module: better error for named exports from cjs · nodejs/node@ad86807
File treeExpand file treeCollapse file tree Open diff view settings fixtures/es-modules/package-cjs-named-error
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/esm/module_job.js +27Lines changed: 27 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | 'use strict'; | 2 | 2 |
| 3 | 3 | const { | | 4 | + ArrayPrototypeJoin, | 4 | 5 | ObjectSetPrototypeOf, | 5 | 6 | PromiseAll, | 6 | 7 | SafeSet, | 7 | 8 | SafePromise, | | 9 | + StringPrototypeIncludes, | | 10 | + StringPrototypeMatch, | | 11 | + StringPrototypeSplit, | 8 | 12 | } = primordials; | 9 | 13 |
| 10 | 14 | const { ModuleWrap } = internalBinding('module_wrap'); | @@ -93,6 +97,29 @@ class ModuleJob { | 93 | 97 | } | 94 | 98 | } catch (e) { | 95 | 99 | decorateErrorStack(e); | | 100 | + if (StringPrototypeIncludes(e.message, | | 101 | + ' does not provide an export named')) { | | 102 | + const splitStack = StringPrototypeSplit(e.stack, '\n'); | | 103 | + const parentFileUrl = splitStack[0]; | | 104 | + const childSpecifier = StringPrototypeMatch(e.message, /module '(.*)' does/)[1]; | | 105 | + const childFileURL = | | 106 | + await this.loader.resolve(childSpecifier, parentFileUrl); | | 107 | + const format = await this.loader.getFormat(childFileURL); | | 108 | + if (format === 'commonjs') { | | 109 | + const importStatement = splitStack[1]; | | 110 | + const namedImports = StringPrototypeMatch(importStatement, /{.*}/)[0]; | | 111 | + e.message = `The requested module '${childSpecifier}' is expected ` + | | 112 | + 'to be of type CommonJS, which does not support named exports. ' + | | 113 | + 'CommonJS modules can be imported by importing the default ' + | | 114 | + 'export.\n' + | | 115 | + 'For example:\n' + | | 116 | + `import pkg from '${childSpecifier}';\n` + | | 117 | + `const ${namedImports} = pkg;`; | | 118 | + const newStack = StringPrototypeSplit(e.stack, '\n'); | | 119 | + newStack[3] = `SyntaxError: ${e.message}`; | | 120 | + e.stack = ArrayPrototypeJoin(newStack, '\n'); | | 121 | + } | | 122 | + } | 96 | 123 | throw e; | 97 | 124 | } | 98 | 125 | for (const dependencyJob of jobsInGraph) { | |
Collapse file Copy file name to clipboard +64Lines changed: 64 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import '../common/index.mjs'; | | 2 | +import { rejects } from 'assert'; | | 3 | + | | 4 | +const fixtureBase = '../fixtures/es-modules/package-cjs-named-error'; | | 5 | + | | 6 | +const expectedRelative = 'The requested module \'./fail.cjs\' is expected to ' + | | 7 | + 'be of type CommonJS, which does not support named exports. CommonJS ' + | | 8 | + 'modules can be imported by importing the default export.\n' + | | 9 | + 'For example:\n' + | | 10 | + 'import pkg from \'./fail.cjs\';\n' + | | 11 | + 'const { comeOn } = pkg;'; | | 12 | + | | 13 | +const expectedPackageHack = 'The requested module \'./json-hack/fail.js\' is ' + | | 14 | + 'expected to be of type CommonJS, which does not support named exports. ' + | | 15 | + 'CommonJS modules can be imported by importing the default export.\n' + | | 16 | + 'For example:\n' + | | 17 | + 'import pkg from \'./json-hack/fail.js\';\n' + | | 18 | + 'const { comeOn } = pkg;'; | | 19 | + | | 20 | +const expectedBare = 'The requested module \'deep-fail\' is expected to ' + | | 21 | + 'be of type CommonJS, which does not support named exports. CommonJS ' + | | 22 | + 'modules can be imported by importing the default export.\n' + | | 23 | + 'For example:\n' + | | 24 | + 'import pkg from \'deep-fail\';\n' + | | 25 | + 'const { comeOn } = pkg;'; | | 26 | + | | 27 | +rejects(async () => { | | 28 | + await import(`${fixtureBase}/single-quote.mjs`); | | 29 | +}, { | | 30 | + name: 'SyntaxError', | | 31 | + message: expectedRelative | | 32 | +}, 'should support relative specifiers with single quotes'); | | 33 | + | | 34 | +rejects(async () => { | | 35 | + await import(`${fixtureBase}/double-quote.mjs`); | | 36 | +}, { | | 37 | + name: 'SyntaxError', | | 38 | + message: expectedRelative | | 39 | +}, 'should support relative specifiers with double quotes'); | | 40 | + | | 41 | +rejects(async () => { | | 42 | + await import(`${fixtureBase}/json-hack.mjs`); | | 43 | +}, { | | 44 | + name: 'SyntaxError', | | 45 | + message: expectedPackageHack | | 46 | +}, 'should respect recursive package.json for module type'); | | 47 | + | | 48 | +rejects(async () => { | | 49 | + await import(`${fixtureBase}/bare-import-single.mjs`); | | 50 | +}, { | | 51 | + name: 'SyntaxError', | | 52 | + message: expectedBare | | 53 | +}, 'should support bare specifiers with single quotes'); | | 54 | + | | 55 | +rejects(async () => { | | 56 | + await import(`${fixtureBase}/bare-import-double.mjs`); | | 57 | +}, { | | 58 | + name: 'SyntaxError', | | 59 | + message: expectedBare | | 60 | +}, 'should support bare specifiers with double quotes'); | | 61 | + | | 62 | +rejects(async () => { | | 63 | + await import(`${fixtureBase}/escaped-single-quote.mjs`); | | 64 | +}, /import pkg from '\.\/oh'no\.cjs'/, 'should support relative specifiers with escaped single quote'); |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import { comeOn } from "deep-fail"; |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import { comeOn } from 'deep-fail'; |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import { comeOn } from "./fail.cjs"; |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import { value } from "./oh'no.cjs"; |
Collapse file Copy file name to clipboard +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +module.exports = { | | 2 | + comeOn: 'fhqwhgads' | | 3 | +}; |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import { comeOn } from './json-hack/fail.js'; |
Collapse file Copy file name to clipboard +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +module.exports = { | | 2 | + comeOn: 'fhqwhgads' | | 3 | +}; |
Collapse file Copy file name to clipboard +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +{ | | 2 | + "type": "commonjs" | | 3 | +} |
|