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

package.exports: false is not working with module loader #32107

Closed
JLHwung opened this issue Mar 5, 2020 · 24 comments
Closed

package.exports: false is not working with module loader #32107

JLHwung opened this issue Mar 5, 2020 · 24 comments
Assignees
Labels
doc Issues and PRs related to the documentations. esm Issues and PRs related to the ECMAScript Modules implementation.

Comments

@JLHwung
Copy link
Contributor

JLHwung commented Mar 5, 2020

Edits:

If you come here via search engine and @babel/* complaints such errors after you upgraded to node.js 12.17.0 or 13.10.0, please update @babel/helper-compilation-targets to latest version.

If you are not using babel directly, please update your build infra (react-scripts, vue-cli and others to name) to latest version. If they doesn't work, the last resort is to remove your package lockfiles and re-install.

--- Original Post ---

  • Version: v13.10.1
  • Platform: Darwin jh.local 19.3.0 Darwin Kernel Version 19.3.0: Thu Jan 9 20:58:23 PST 2020; root:xnu-6153.81.5~1/RELEASE_X86_64 x86_64
  • Subsystem: ES Modules

What steps will reproduce the bug?

  1. Create a package foo, with package.json as
{
  "exports": false
}
  1. add a test file test.js.
require("foo")

How often does it reproduce? Is there a required condition?

Must reproduce

What is the expected behavior?

It should load successfully according to the docs

If a package has no exports, setting "exports": false can be used instead of "exports": {} to indicate the package does not intend for submodules to be exposed.

What do you see instead?

It throws

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main resolved in /path/to/foo/package.json

Additional information

exports: {} also throws.
exports: null looks good to me but it is undocumented.

The issue is firstly reported in babel/babel#11216, we had changed exports: false to exports: { ".": "./lib/index.js" } for backward compatibility to Node.js 13.0-13.1. But I don't expect exports: false will break on Node.js 13.10

I am not familiar with ES modules spec. So if this behaviour is intended, please update the docs.

@BassemN
Copy link

BassemN commented Mar 5, 2020

I'm getting the same error after updating to v13.10.1 so I switched back to LTS v12.16.1 and the error gone.

@BassemN
Copy link

BassemN commented Mar 5, 2020

I fixed this issue by removing the node_modules directory and package-lock.json file then run npm install to fresh install all packages then the issue was fixed.

@bmhatfield
Copy link

I am able to confirm that @BassemN 's advice of removing node_modules and package-lock.json on node v13.10.1 resolved this issue for me as well. Removing only node_modules was not sufficient.

@MylesBorins MylesBorins added the esm Issues and PRs related to the ECMAScript Modules implementation. label Mar 6, 2020
@MylesBorins
Copy link
Contributor

/cc @nodejs/modules

@ljharb
Copy link
Member

ljharb commented Mar 6, 2020

The exports field value should always be unconditionally passed into Object.keys, such that any primitive value is treated the same as an empty object (which should mean, “defer to main, nothing else is reachable”)

@MylesBorins
Copy link
Contributor

I've got a patch to revert to the behavior documented in the README. It is not clear to me if this was intended / desired behavior change... but I am assuming it is not as the docs were not updated.

I'll open a PR and we can discuss it.

@GeoffreyBooth
Copy link
Member

There was a recent change by @jkrems or @guybedford to stop unintended falling back to "main" for unmatched conditions, maybe that introduced a bug?

MylesBorins added a commit to MylesBorins/node that referenced this issue Mar 6, 2020
@MylesBorins
Copy link
Contributor

MylesBorins commented Mar 6, 2020

it seems like behavior has changed for both exports: false and exports: {}.

My original patch doesn't work as it is supposed to unfortunately although the tests I wrote can likely be resused. I found a way to make "false" work, but it completely skips all the exports checks and there is also no support for {}... so I obviously didn't do it right. It's late and I'm done for now, but here is the commit in case anyone wants to pick it up.

@unilynx
Copy link

unilynx commented Mar 6, 2020

for us this was explicitly triggered by babel 7.8.3 - the exports:false was here: https://github.com/babel/babel/blob/v7.8.3/packages/babel-helper-compilation-targets/package.json

upgrading to 7.8.7 appears to resolve it

@guybedford
Copy link
Contributor

The semantics of "exports" are that the field is only ever parsed when not null or undefined. When it is parsed, if it is not valid then that behaves as if there are no exports of the package (including the main, since the main is an export).

I think this is actually a docs issue, since "exports": false was a feature before the exports main was fully supported - we previously treated subpaths and the main differently such that exports only applied to subpaths and "exports": false could make sense to disable subpaths.

I've created a docs update in 74206e7 to remove reference to the "exports": false case, and rather encourage using the exports main always as the pattern here.

I think that would make sense as guidance to always encourage setting the exports main as in this docs update.

Thanks for posting @JLHwung this is definitely a confusion that would be good to fix.

@ljharb
Copy link
Member

ljharb commented Mar 6, 2020

@guybedford when did we discuss changing it? As i recall, it’s supposed to always be passed into Object.keys when it’s non-nullish, making false and true and {} equivalent.

@guybedford
Copy link
Contributor

guybedford commented Mar 6, 2020 via email

@ozanmanav
Copy link

I'm getting the same error after updating to v13.10.1 so I switched back to LTS v12.16.1 and the error gone.

This is the fix, I used node13-alpine in the docker file, because of that i was getting this error. Now i fixed to 12.6.1 and error is gone. (althought i upgraded babel to latest )

@guybedford
Copy link
Contributor

There is a Babel bug here that was fixed in a patch. See https://github.com/babel/babel/pull/11006/files.

@JLHwung
Copy link
Contributor Author

JLHwung commented Mar 9, 2020

There is a Babel bug here that was fixed in a patch. See https://github.com/babel/babel/pull/11006/files.

That patch is supposed to offer backward compatibility: At that moment exports: false was recommended in docs but it was not supported in node.js 13.0-13.1.

@ljharb
Copy link
Member

ljharb commented Mar 9, 2020

To support those node versions, you need to use an array, so the object form can fall back to the string form.

@jkrems
Copy link
Contributor

jkrems commented Mar 9, 2020

I think in this case, it's enough to just use the string form. The current value:

  "main": "lib/index.js",
  "exports": {
    ".": "./lib/index.js"
  },

Could also be written as:

  "main": "lib/index.js",
  "exports": "./lib/index.js",

@mlittlec
Copy link

mlittlec commented Mar 9, 2020

I'm getting the same error after updating to v13.10.1 so I switched back to LTS v12.16.1 and the error gone.

This is the fix, I used node13-alpine in the docker file, because of that i was getting this error. Now i fixed to 12.6.1 and error is gone. (althought i upgraded babel to latest )

This worked for me too - I moved back to the LTS (12.6.1) version on my Ubuntu install via this command sudo n stable

@bmartel
Copy link

bmartel commented Apr 28, 2020

for us this was explicitly triggered by babel 7.8.3 - the exports:false was here: https://github.com/babel/babel/blob/v7.8.3/packages/babel-helper-compilation-targets/package.json

upgrading to 7.8.7 appears to resolve it

I ran into this upon upgrading to node 12.6.3 from 10.20.1, just wanted to mention that this definitely resolves my case. I also want to mention for others possibly running @babel/register for server side compilation to ensure it is also upgraded to match otherwise you will continue to get the same error for the server side compilation step. I forgot I even had it which seems to always be the case once something works for a long time 😄.

Averethel added a commit to carforyou/carforyou-components-pkg that referenced this issue May 19, 2020
There's a bug in nodejs: nodejs/node#32107 that prevents babel 7.8.3 from working in node 13.10+

Te workaround was added in 7.8.4
Averethel added a commit to carforyou/carforyou-components-pkg that referenced this issue May 26, 2020
* chore: switch to eslint rules

* chore: update babel

There's a bug in nodejs: nodejs/node#32107 that prevents babel 7.8.3 from working in node 13.10+

Te workaround was added in 7.8.4

* chore: ingore pkg directory from linting

* chore: include `stories` in tsconfig

* chore: prettier on files that haven't been linted before

* chore: use jest.fn for mocks

* chore: no unused vars

* chore: not needed escape

* chore: prototype method call

* chore: disable require rule

* chore: disable prefer rest

This is a 3rd part intercom snippet.

* chore: switch to slint comment

* fix: no implicit any

* chore: disable naming convention rule

* chore: remove legacy ts-lint comments

* chore: pass input type

* chore: bump lint rules
kailo777 pushed a commit to kailo777/crwn-clothing that referenced this issue Jun 5, 2020
@smoak
Copy link

smoak commented Jun 9, 2020

Just adding that I get this issue with node versions 12.18.0 and 12.17.0 but it does not reproduce with node version 12.16.3. Platform: Linux myarch 5.4.42-1-lts SMP Wed, 20 May 2020 20:42:53 +0000 x86_64 GNU/Linux

@guybedford
Copy link
Contributor

exports: false is the same as exports: {} or having a package that cannot be loaded at all!

You don't want to ever use it.

To give some background here for those interested, in an early iteration of the "exports" field, it used to only provide subpath exports, and work alongside the "main". It was a later change in the development of this field to make it also apply to the main and provide the conditional mapping features to the main. Before it applied to the main "exports": false could be used to indicate a package that was encapsulated and could be only loaded via the main, but since the main was also included in its definition, "exports": false will now not even load the "main".

Any packages published with this pattern are shipping a bug, so you likely want to upgrade any dependency that is using this "exports": false" definition to fix the issue.

There should be enough information in this thread for anyone hitting this issue, closing this as a non-bug.

amacleay-cohere added a commit to amacleay-cohere/restful-react that referenced this issue Jul 8, 2020
This is a bug in babel: babel/babel#11216
It is closed but points to an issue in node: nodejs/node#32107
The issue in node is closed as not an issue, so it seems as though babel needs to fix.

Also, check that build works in PRs.
fabien0102 pushed a commit to contiamo/restful-react that referenced this issue Jul 10, 2020
This is a bug in babel: babel/babel#11216
It is closed but points to an issue in node: nodejs/node#32107
The issue in node is closed as not an issue, so it seems as though babel needs to fix.

Also, check that build works in PRs.
@BirgitPohl
Copy link

I'm getting the same error after updating to v13.10.1 so I switched back to LTS v12.16.1 and the error gone.

Because of this hint I switched from LTS v12.18.2 to LTS v12.16.1 and got this resolved.
I have a clean installation straight from Github.
No changed were made in my repo that worked before and after resolving.

As far as I can read babel has referred to the Node community to resolve this.

@jkrems
Copy link
Contributor

jkrems commented Aug 5, 2020

@BirgitPohl I think the babel package is fixed in the latest version (https://github.com/babel/babel/blob/7fd40d86a0d03ff0e9c3ea16b29689945433d4df/packages/babel-helper-compilation-targets/package.json#L13-L15) - or at least should be. If this happens with a different package, it may require a similar fix to its package.json.

@guybedford
Copy link
Contributor

If this version of the Babel helper continues to cause problems one approach might be to land supporting non-object exports as being warnings while behaving as if exports does not exist.

sveneh pushed a commit to wuerthcs/geteventstore-promise that referenced this issue Sep 21, 2020
sveneh pushed a commit to wuerthcs/geteventstore-promise that referenced this issue Sep 21, 2020
akre54 added a commit to akre54/react-dat-gui that referenced this issue Oct 6, 2020
See nodejs/node#32107 (comment)

This breaks the module loader on versions newer than node 12.16.x
claus pushed a commit to claus/react-dat-gui that referenced this issue Mar 30, 2021
See nodejs/node#32107 (comment)

This breaks the module loader on versions newer than node 12.16.x
claus pushed a commit to claus/react-dat-gui that referenced this issue Mar 30, 2021
See nodejs/node#32107 (comment)

This breaks the module loader on versions newer than node 12.16.x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. esm Issues and PRs related to the ECMAScript Modules implementation.
Projects
None yet
Development

Successfully merging a pull request may close this issue.