-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Misleading error that module does not provide export #32137
Comments
node/lib/internal/modules/esm/get_format.js Lines 58 to 59 in c49286b
and node/lib/internal/modules/esm/loader.js Lines 201 to 218 in c49286b
node/lib/internal/modules/esm/translators.js Lines 92 to 116 in c49286b
|
|
There seems to be a bug here in the loader itself. This module should not be loaded as ESM, but rather as CJS. Was able to make the repro even smaller index.mjs import { foo } from './index.cjs';
console.log(foo()); index.cjs export function foo() {
return 'foo';
} Even though this has ESM syntax in it it should fail to even import as you are attempting to do a named exports of the CJS module. pinging @jkrems and @guybedford to take a look |
I don't think it's a bug, because you not mark the file as the |
Maybe I'm missing something but this looks to error correctly because of the lack of an export named
|
why correctly? when import { foo } from '../lib/index.js'; import {foo} from '../lib/index.js';
^^^
SyntaxError: The requested module '../lib/index.js' does not provide an export named 'foo' but, when import foo from '../lib/index.js';
``
```bash
export function foo() {
^^^^^^
SyntaxError: Unexpected token 'export' this is two kinds of different error types, and the first error message will misleading users. |
another example // change https://github.com/dandv/lib-does-not-provide-export-foo/blob/master/lib/index.js
exports.foo = 123 the error message still occur import { foo } from '../lib/index.js';
^^^
SyntaxError: The requested module '../lib/index.js' does not provide an export named 'foo' but I change import md from '../lib/index.js';
console.log(md); thing go weird (node:24052) ExperimentalWarning: The ESM module loader is experimental.
{ foo: 123 } |
I guess that cjs module loader make all codes node/lib/internal/modules/esm/translators.js Line 109 in 73f2dbc
|
I'm not saying it's not confusing right now. The issue is just: This happens before we even try to run the code and that's when a CommonJS syntax errors would happen. It may be possible to somehow detect this specific error and try to gather some more context but it would be tricky. To go into what you were seeing in your last comment: Exports in ES modules are very different from the "exports" object in CommonJS, confusingly. Each module export is a variable/identifier. The following CommonJS code doesn't create a new variable, it only sets a property on one: exports.foo = 123 So afterwards the CommonJS still only has a single export - the import { default as md } from '../lib/index.js';
console.log(md); So your importing the |
Yeah, I get you |
Marking as a documentation issue since this is a common error that should be well documented. //cc @GeoffreyBooth |
I think this needs more than just documentation. If you directly run
I would have wanted this case to show a better SyntaxError, and maybe a warning, something like:
I'll note that the error is marginally better if you try to import the default export without braces, like this:
|
I just realized that the scope of this is bigger than "ESM misinterpreted as CJS." This error applies even when the imported script is legit CJS with named exports. dependency.cjs module.exports.name = "foo"; dependent.mjs import {name} from './dependency.cjs';
console.log({name}); You get this: The SyntaxError in this case should be much clearer:
|
How do you re-write this so it works? |
This error was considerably enhanced in Node 14.8 I believe. Now the error message says:
And, indeed, that's what you'd do to fix
|
@dandv @dfabulich @kathy-ems Node.js 14.13.0 added support for named CJS exports, see #35249 and this change has also been backported to Node.js v12.20.0. Can you confirm that
now also works for you if |
sveltejs#1000). See my comment sveltejs#1000 (comment) references >Node.js 14.13.0 added support for named CJS exports, see #35249 and this change has also been backported to Node.js v12.20.0. nodejs/node#32137 (comment) and >Yep, it was fixed after downloading 14.13.1, thank you nodejs/node#35249 (comment)
Use the suggested code from the error message. Closing as I think this has been addressed. |
What do we do when it's a dependency that's doing the I'm receiving this error and don't have control over the dependency's code. Any suggestions? |
Have you tried reporting this as a bug to the dependency which is causing the issue? |
Yeah you have to provide a fix in the repo. I'm facing this currently and it's a bit frustrating. |
What steps will reproduce the bug?
git clone https://github.com/dandv/lib-does-not-provide-export-foo
cd lib-does-not-provide-export-foo/use-lib
node use-it.js # node v13.9.0
What is the expected behavior?
The script should run and output
foo
.What do you see instead?
Additional information
Within the context of a large project, this was a pretty odd mystery, when
lib/index.js
clearly exportsfoo
. Feel free to have some fun figuring out it (not hard with the minimal repro repo, but imagine the confused looks in a real-world scenario). Solution below..
.
.
.
.
.
.
.
.
.
Solution
lib/package.json lacks
"type": "module"
.Proposal
A clearer error would indicate that the imported file is not a module at all. As it is, the error suggested that other symbols were exported fine, so I kept double checking for typos and what not. This happened during a conversion to TypeScript that involved adding one export. The error made me think the problem was that export; it was not - it was that I forgot to add
"type": "module"
topackage.json
.The full title of the bug would be "Misleading error that module does not provide export when "module" is not in fact a module", but that would have been a spoiler.
The text was updated successfully, but these errors were encountered: