You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
package.exports: false is not working with module loader #32107
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?
Create a package foo, with package.json as
{
"exports": false
}
add a test file test.js.
require("foo")
How often does it reproduce? Is there a required condition?
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.
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.
Reacted by Brian Reeves, Raffael Dzikowski, Chris Chacholiades, abaran3, Aleksandar, Avet Antonyan, Alvaro, Branch Archer, Frank Santos, Liam and 7 more
Reacted by Aleksandar, Branch Archer, Frank Santos, Liam, Eleazar Resendez, Alexey808, Abhinand Shetty, Imran Hassan and gregg-cbs
Reacted by Abhinand Shetty
Reacted by Frank Santos, Alexey808, Abhinand Shetty and stardev-123
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 onlynode_modules was not sufficient.
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”)
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.
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.
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.
Reacted by Huáng Jùnliàng, Jan Olaf Martin, Jordan Harband and Alex Yang
@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.
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
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.
Reacted by Jordan Harband, VincentN and Steven Grimaldo
Reacted by Huáng Jùnliàng, Jan Olaf Martin, Jordan Harband, Matteo Collina and Hassan Sani
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.
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.
Activity
BassemN commentedon 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 commentedon Mar 5, 2020
I fixed this issue by removing the
node_modulesdirectory andpackage-lock.jsonfile then runnpm installto fresh install all packages then the issue was fixed.bmhatfield commentedon Mar 5, 2020
I am able to confirm that @BassemN 's advice of removing
node_modulesandpackage-lock.jsonon node v13.10.1 resolved this issue for me as well. Removing onlynode_moduleswas not sufficient.MylesBorins commentedon Mar 6, 2020
/cc @nodejs/modules
ljharb commentedon 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 tomain, nothing else is reachable”)MylesBorins commentedon Mar 6, 2020
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 commentedon Mar 6, 2020
There was a recent change by @jkrems or @guybedford to stop unintended falling back to
"main"for unmatched conditions, maybe that introduced a bug?module: bring back support for exports: false
MylesBorins commentedon Mar 6, 2020
it seems like behavior has changed for both
exports: falseandexports: {}.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 commentedon 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 commentedon Mar 6, 2020
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": falsewas 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": falsecould 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 commentedon 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.14 remaining items
chore: eslint migration (#186)
fix issue nodejs/node#32107
smoak commentedon 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/Linuxguybedford commentedon Jun 11, 2020
exports: falseis the same asexports: {}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": falsecould 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": falsewill 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.
Fix build (babel helper-compilation-targets workaround)
Fix build (babel helper-compilation-targets workaround)
BirgitPohl commentedon Aug 5, 2020
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.
hybrist commentedon 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 commentedon Aug 5, 2020
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.
fix for nodejs/node#32107
Merge pull request #1 from ZIP-Software/sveneh/ch2740/event-store-clo…
exports: false breaks node module loader
exports: false breaks node module loader
exports: false breaks node module loader