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

Deno uses "node" condition instead of "deno" when "node" condition placed first in package.json exports resolution #26789

Closed
panva opened this issue Nov 8, 2024 · 6 comments
Labels
invalid what appeared to be an issue with Deno wasn't

Comments

@panva
Copy link
Contributor

panva commented Nov 8, 2024

Refs: wintercg/runtime-keys#5
Refs: wintercg/runtime-keys#18

One can easily believe that the following exports condition examples mean "everything but node loads from the webapi dist".

"exports": {
    "node": "./dist/node/index.js",
    "deno": "./dist/deno/index.js"
},
"exports": {
    "node": "./dist/node/index.js",
    "default": "./dist/webapi/index.js"
},

Unfortunately Deno will load the "node" condition in both examples above despite there being a default or, even worse offense, an explicit "deno" one.

@dsherret
Copy link
Member

dsherret commented Nov 8, 2024

Isn't this by design? You need to put "deno" before "node" in this case so that Deno loads the first matching condition (and Deno matches the "node" condition).

Within the "exports" object, key order is significant. During condition matching, earlier entries have higher priority and take precedence over later entries. The general rule is that conditions should be from most specific to least specific in object order.

https://nodejs.org/api/packages.html#conditional-exports

@dsherret dsherret added the question a question about the use of Deno label Nov 8, 2024
@dsherret dsherret changed the title issues with package.json exports resolution Deno uses "node" condition instead of "deno" when "node" condition placed first in package.json exports resolution Nov 8, 2024
@panva
Copy link
Contributor Author

panva commented Nov 8, 2024

This is not a question a question about the use of Deno , I know how to work around this.

I am pointing out that this is bad and more importantly, not expected, behaviour, especially in the first case when there is a Deno-specific export.

@panva
Copy link
Contributor Author

panva commented Nov 8, 2024

As a module author I want to be able to write a module that exports "for node" and "for everything else" with two simple exports. And Deno (and also Bun's) behaviour is in the way of being able to do that.

@dsherret
Copy link
Member

dsherret commented Nov 8, 2024

From my understanding of...

Within the "exports" object, key order is significant. During condition matching, earlier entries have higher priority and take precedence over later entries. The general rule is that conditions should be from most specific to least specific in object order.

...you need to do the following:

"exports": {
    "deno": "./dist/deno/index.js",
    "node": "./dist/node/index.js"
},

...because otherwise Deno will match the "node" condition. It's critical Deno matches the "node" condition or else many packages will not work properly.

@dsherret dsherret added invalid what appeared to be an issue with Deno wasn't and removed question a question about the use of Deno labels Nov 8, 2024
@panva
Copy link
Contributor Author

panva commented Nov 8, 2024

If you're going to treat this like a Question I'm going to ask one: Please explain how a module author can achieve

module that exports "for node" and "for everything else" with two simple exports

Without Deno users being routed to the "node" export which, despite all the marketing, has its edge cases, especially when it comes to specifics of node:crypto?

@dsherret
Copy link
Member

dsherret commented Nov 8, 2024

module that exports "for node" and "for everything else" with two simple exports

You can't do this without having a more specific exports condition above the "node" condition. The default conditions that Deno provides to the exports resolution algorithm is ["deno", "node", "import"], so in order to not match the "node" condition you'll need to provide the "deno" condition first so that gets matched for Deno.

@dsherret dsherret closed this as not planned Won't fix, can't repro, duplicate, stale Nov 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid what appeared to be an issue with Deno wasn't
Projects
None yet
Development

No branches or pull requests

2 participants