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 require "./" in front of path or resolver fails #32034

Closed
MylesBorins opened this issue Mar 1, 2020 · 16 comments
Closed

package.exports require "./" in front of path or resolver fails #32034

MylesBorins opened this issue Mar 1, 2020 · 16 comments
Labels
esm Issues and PRs related to the ECMAScript Modules implementation.

Comments

@MylesBorins
Copy link
Contributor

Had a bug report for one of my module due to resolution issues. Specifically the below doesn't work

{
  "exports": "lib/index.js"
{

But the below does

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

This is inconsistent with the behavior of main where the ./ is not required in relative paths.

To make matters even more confusing there is no failure when attempting to load a module as self-referential.

TBH this seems like a bug. Even if it was intentional design it is very easy to get wrong and was hard to debug.

/cc @nodejs/modules thoughts?

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

ljharb commented Mar 1, 2020

It was intentional (it’s a shame that main and bin don’t require the leading dot), but i very much would not expect a silent failure.

@MylesBorins
Copy link
Contributor Author

MylesBorins commented Mar 1, 2020 via email

@MylesBorins
Copy link
Contributor Author

MylesBorins commented Mar 1, 2020 via email

@ljharb
Copy link
Member

ljharb commented Mar 1, 2020

I very much agree that it needs to have a clear error message, or that it needs to match main.

The behavior of main/bin causes confusion in the ecosystem, and in the case of exports, it seems unclear if a bare identifier on the RHS points to node_modules or to a relative file.

@guybedford
Copy link
Contributor

There were error handling improvements made in the recent PR only landing in the coming release. Improving these errors was one of the things it included if I recall, so it would be worth testing these messages with the upcoming 13 release.

@guybedford
Copy link
Contributor

But to clarify - I could certainly get behind relaxing this restriction to align with user expectations, we were just being cautious in the initial implementation with the design space.

@MylesBorins
Copy link
Contributor Author

MylesBorins commented Mar 1, 2020 via email

@ljharb
Copy link
Member

ljharb commented Mar 2, 2020

I believe that if we relaxed it, it would lock down the design space for the RHS potentially being a bare specifier.

@coreyfarrell
Copy link
Member

I was not able to get self reference to work using "exports": "lib/index.js", @MylesBorins could you retest that or share an example of this incorrectly succeeding?

Would it make sense for documentation to recommend all packages which set package.json#exports also have a version restricted test that uses self reference? This is what I'm doing in tapjs/libtap#10, I created test/libtap.mjs which uses self-reference. The test file is only run on 13.9.0 and up, the goal being to verify that exports is properly setup and that import * as libtap from 'libtap' provides named exports.

A couple notes on documentation:

  • The conditional exports section has no history section - first version to include the feature or when it was unflagged. Is this intentional?
  • I did not find any mention of "self reference" in the ESM documentation page. Is it elsewhere?

@jkrems
Copy link
Contributor

jkrems commented Mar 2, 2020

I did not find any mention of "self reference" in the ESM documentation page. Is it elsewhere?

There's an open PR to fill that gap: #31680

@jkrems
Copy link
Contributor

jkrems commented Mar 2, 2020

This is inconsistent with the behavior of main where the ./ is not required in relative paths.

It is consistent with import maps and the left-hand side of exports. I'd rather have the exports field internally consistent than consistent with another field. In my opinion it would be even worse if we'd end up with:

{
  "exports": {
    "./dot-slash-required-here": "dot-slash-optional-here.js"
  }
}

Especially since on the left side, omitting the leading ./ completely changes the meaning: it's a condition, not a path anymore.

That being said, I agree that we should have a good error message, especially in the single-string case. There definitely is a risk of confusing users during the migration.

@bmeck
Copy link
Member

bmeck commented Mar 2, 2020

If we do relax something, I'd request we do a URL check on the RHS to keep that. I'm not yet convinced that we don't want to do something to the right hand side, but am fairly confident anything we would want to do would work with URLs. This would keep the RHS constrained to https://url.spec.whatwg.org/#relative-url-string in case we want to do look at something like "import:peer_or_inner". The check isn't free though and I do have some concerns about doing such a check as it is more complex than a simple prefix check.

@GeoffreyBooth
Copy link
Member

I'm also not convinced that anything should change here other than better error messaging. Currently the right hand side is (correct me if I'm wrong) consistent with import, in that you can do import './file.js' but not import 'file.js'.

@bmeck
Copy link
Member

bmeck commented Mar 2, 2020

@GeoffreyBooth it's a restricted subset of valid import specifiers. import 'file.js'; works but doesn't do what people might want, it would look in node_modules instead of relatively. exports doesn't support the bare form. Similarly, leading '/' is not supported in exports for now.

@MylesBorins
Copy link
Contributor Author

Based on feedback here I am fine with keeping the current behavior. I opened a PR to improve the error message. It has 0 changes to the runtime or the error code, just a special case error message. It might be a bit too broad of a solution but if you pass a RHS that does not start with a ./ or / it will explicitly point that out

@coreyfarrell
Copy link
Member

@MylesBorins if you have a chance could you give more details about how you bypassed the error using self-reference. IMO this is very important, my own expectation is that a package can/should self-test valid exports by using self-reference.

MylesBorins added a commit to MylesBorins/node that referenced this issue Apr 17, 2020
For targets that are strings that do not start with `./` or `/` the
error will now have additional information about what the programming
error is.

Closes: nodejs#32034
BethGriggs pushed a commit that referenced this issue Apr 27, 2020
For targets that are strings that do not start with `./` or `/` the
error will now have additional information about what the programming
error is.

Closes: #32034

PR-URL: #32052
Fixes: #32034
Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Signed-off-by: Myles Borins <myles.borins@gmail.com>
BridgeAR pushed a commit that referenced this issue Apr 28, 2020
For targets that are strings that do not start with `./` or `/` the
error will now have additional information about what the programming
error is.

Closes: #32034

PR-URL: #32052
Fixes: #32034
Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Signed-off-by: Myles Borins <myles.borins@gmail.com>
targos pushed a commit that referenced this issue Apr 30, 2020
For targets that are strings that do not start with `./` or `/` the
error will now have additional information about what the programming
error is.

Closes: #32034

PR-URL: #32052
Fixes: #32034
Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Signed-off-by: Myles Borins <myles.borins@gmail.com>
targos pushed a commit that referenced this issue May 13, 2020
For targets that are strings that do not start with `./` or `/` the
error will now have additional information about what the programming
error is.

Closes: #32034

PR-URL: #32052
Fixes: #32034
Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Signed-off-by: Myles Borins <myles.borins@gmail.com>
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.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants