Skip to content
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

SyntaxError: Named export not found starting v16.0.0-nightly20201030 #35893

Closed
pubmikeb opened this issue Oct 31, 2020 · 16 comments
Closed

SyntaxError: Named export not found starting v16.0.0-nightly20201030 #35893

pubmikeb opened this issue Oct 31, 2020 · 16 comments
Labels
esm Issues and PRs related to the ECMAScript Modules implementation. module Issues and PRs related to the module subsystem.

Comments

@pubmikeb
Copy link

pubmikeb commented Oct 31, 2020

Starting from the version v16.0.0-nightly20201030e8fe38f7cf I experience the issue with named import of Dropbox:

import {Dropbox} from "dropbox";
        ^^^^^^^
SyntaxError: Named export 'Dropbox' not found. The requested module 'dropbox' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'dropbox';
const {Dropbox} = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:98:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:143:5)
    at async Loader.import (node:internal/modules/esm/loader:165:24)
    at async Object.loadESM (node:internal/process/esm_loader:68:5)

Process finished with exit code 1

If I rollback to the previous nightly build v16.0.0-nightly20201029bec918fb9b, then everything is perfectly working. Therefore, I assume that the issue can be in Node.js and not in the way I import the package or in Dropbox itself.

Can it be somehow related to the Node.js transition to ecmaVersion 2021?

@pubmikeb pubmikeb changed the title SyntaxError: Named export not found. SyntaxError: Named export not found starting v16.0.0-nightly20201030 Oct 31, 2020
@DerekNonGeneric
Copy link
Contributor

As the error says, 'dropbox' is a CommonJS module. This is evident as they do not have an exports key and are using main. You're going to want to use the default export instead.

import dropbox from "dropbox";

You probably added the following line recently.

import {Dropbox} from "dropbox";

Remove it since you're already doing what's necessary to import the module and destructure the class.

import pkg from 'dropbox';
const {Dropbox} = pkg;

Check out the last sentence in import statements section.

Like in CommonJS, files within packages can be accessed by appending a path to the package name; unless the package’s package.json contains an "exports" field, in which case files within packages need to be accessed via the path defined in "exports".
https://nodejs.org/dist/latest-v15.x/docs/api/esm.html#esm_import_statements

Hope that helps. :)

@targos
Copy link
Member

targos commented Oct 31, 2020

/cc @guybedford This seems related to nodejs/cjs-module-lexer#24

Code of the dropbox package: https://unpkg.com/dropbox@7.3.0/cjs/index.js

Edit: it seems like it was intentional, but isn't it going to break named imports for all modules compiled with babel?

@pubmikeb
Copy link
Author

pubmikeb commented Oct 31, 2020

You probably added the following line recently.

import {Dropbox} from "dropbox";

No, this line was in the codebase before I've faced the issue.

Remove it since you're already doing what's necessary to import the module and destructure the class.

import pkg from 'dropbox';
const {Dropbox} = pkg;

It is proposed by Node.js in the error message, but doesn't exist in the codebase.

The problem point is that prior v16.0.0-nightly20201030 everything used to work correctly.

@DerekNonGeneric
Copy link
Contributor

Is proposed by Node.js in the error message, but doesn't exist in the codebase.

If that is the case, you probably found a bug since that doesn't seem right.

@pubmikeb
Copy link
Author

If that is the case, you probably found a bug since that doesn't seem right.

I'm trying to prepare a sample project for the case reproduction.

@DerekNonGeneric DerekNonGeneric added esm Issues and PRs related to the ECMAScript Modules implementation. module Issues and PRs related to the module subsystem. labels Oct 31, 2020
@pubmikeb
Copy link
Author

pubmikeb commented Oct 31, 2020

I've succeeded to localize the issue and arranged it as a standalone IDEA/WebStorm-project.

Repro steps:

  1. Install v16.0.0-nightly20201029bec918fb9b
  2. Open the project in IDEA/WebStorm (alternatives are also possible…)
  3. Install dependencies
  4. Run the project, no error will be in console
  5. Install v16.0.0-nightly20201030e8fe38f7cf
  6. Run the project, you'll get the error from the initial post.

@aduh95
Copy link
Contributor

aduh95 commented Oct 31, 2020

I'm able to reproduce:

$ curl -L https://unpkg.com/dropbox@7.3.0/cjs/index.js > dropbox.cjs
$ echo "import {Dropbox} from './dropbox.cjs';" > entry.mjs
$ mkdir src
$ echo "module.exports = { default: {} };" > src/auth.js
$ echo "module.exports = { default: {} };" > src/dropbox.js
$ node-without-b92d2e4b78 entry.mjs
$ node-with-b92d2e4b78 entry.mjs
file://…/entry.mjs:1
import {Dropbox} from './dropbox.cjs';
        ^^^^^^^
SyntaxError: Named export 'Dropbox' not found. The requested module './dropbox.cjs' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from './dropbox.cjs';
const {Dropbox} = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:98:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:143:5)
    at async Loader.import (node:internal/modules/esm/loader:165:24)
    at async Object.loadESM (node:internal/process/esm_loader:68:5)

Related to b92d2e4.

@DerekNonGeneric
Copy link
Contributor

@pubmikeb, thanks for doing that. Would it be possible for you to make a public GitHub repo with that instead?

@pubmikeb
Copy link
Author

pubmikeb commented Oct 31, 2020

@pubmikeb, thanks for doing that. Would it be possible for you to make a public GitHub repo with that instead?

Done.

P.S. Please, let me know when this repo can be deleted.

@guybedford
Copy link
Contributor

This was exactly the breaking change described in #35871.

If you look at the Dropbox index file you can see it is using getters to describe the interface:

https://unpkg.com/dropbox@7.3.0/cjs/index.js

Because all getters are called at the time of import, we disabled detecting getters for better compatibility as if one of those getters caused a harmful side effect then there would be no way to import Dropbox at all.

So this was a decision to worsten the detection in the name of compatibility. I'm open to reconsidering the exact mechanics, and we can potentially detect non-harmful getters somehow even in future to reenable this stuff, but the stable baseline not including getters seems a sensible line to draw for now.

@targos
Copy link
Member

targos commented Oct 31, 2020

Il misunderstood the breaking change in that PR. I thought it would special case files with an __esModule export, not just that export.

@guybedford
Copy link
Contributor

guybedford commented Oct 31, 2020

The only special case for __esModule is that it is still detected as a named export despite being a getter (import * as dropbox from 'dropbox'; dropbox.__esModule === true), not that it enables other getter detections.

(Getters are not used in Babel or TypeScript outputs, apart from for star reexports which still work correctly)

@guybedford
Copy link
Contributor

I've implemented a fix for these style of reexport getters in #35901.

@pubmikeb
Copy link
Author

pubmikeb commented Nov 1, 2020

So this was a decision to worsen the detection in the name of compatibility.

Well, a fix in the name of compatibility, which actually breaks the compatibility (previously worked code)…

Good that I discovered this problem right after the «fix» had been deployed and not at the migration to v.16 RTM.

@aduh95
Copy link
Contributor

aduh95 commented Nov 1, 2020

@pubmikeb #35901 has landed on master with a fix for the issue you reported, it should be available in the next v15 release – and on nightly builds until then. I'm going to close this now, please reopen if you find another bug.

Thank you for being vigilant, it's kinda cool this compatibility bug was fixed before an actual release of Node.js 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
esm Issues and PRs related to the ECMAScript Modules implementation. module Issues and PRs related to the module subsystem.
Projects
None yet
Development

No branches or pull requests

5 participants