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

fix(node-resolve): Fix package exports / imports resolution algorithm #1549

Merged
merged 1 commit into from
Aug 22, 2023

Conversation

susnux
Copy link
Contributor

@susnux susnux commented Aug 3, 2023

Rollup Plugin Name: node-resolve

This PR contains:

  • bugfix
  • feature
  • refactor
  • documentation
  • other

Are tests included?

  • yes (bugfixes and features will not be merged without tests)
  • no

Breaking Changes?

  • yes (breaking changes will not be merged unless absolutely necessary)
  • no

If yes, then include "BREAKING CHANGES:" in the first commit message body, followed by a description of what is breaking.

List any relevant issue numbers:

Description

Currently the implementation of package exports / imports resolution does not follow the Node documentation as the README implies.
So this fixes the package exports and imports resolution algorithm by strictly following the Node API documentation. For backwards compatibility a new option allowExportsFolderMapping is introduced which will enable deprecated folder mappings.

This is required for packages that use export patterns with the asterisk in the middle not at the end, like this:

{
  "exports": {
    "./component/*.js": {
      "import": "./dist/*.mjs",
      "require": "./dist/*.cjs"
    }
  }
}

See included test file.

@shellscape
Copy link
Collaborator

Thanks for the PR. @guybedford is our resident resolutions expert, hoping he sees this and offers thoughts.

Copy link
Member

@lukastaegert lukastaegert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really looks massive and appears to contain many subtle improvements. It also appears you checked against the original algorithm, is that true?
Admittedly, the TypeScript conversion both is very useful and makes comparing the diff rather hard. For other reviewers, the relevant files to look at are resolvePackageImportsExports.ts and resolvePackageTarget.ts as only those contain major changes.

I do not feel confident to 100% judge the accuracy of the algorithm, but I would hope this feature can land as it seems to fix everything that might subtly differ from the Node algorithm.

Comment on lines +52 to +51
// Assert: ends with "/" or contains only a single "*".
.filter((k) => k.endsWith('/') || k.includes('*'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You say you only want patterns that contain a single *, but this will also keep patterns with multiple *, is this intended?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how the algorithm is written - basically multiple ** are invalid, but we don't ban them outright in case it might be supported in future - so instead they are filtered out by omission since they can never be matched.

Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry didn't spot this at first. Great to have the spec comments in here - this is excellent work thank you!

Comment on lines +52 to +51
// Assert: ends with "/" or contains only a single "*".
.filter((k) => k.endsWith('/') || k.includes('*'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how the algorithm is written - basically multiple ** are invalid, but we don't ban them outright in case it might be supported in future - so instead they are filtered out by omission since they can never be matched.

@shellscape
Copy link
Collaborator

@lukastaegert I'll leave this one up to you to merge when you're happy with the convo with @guybedford

…orithm according to Node documentation

This fixes the package exports and imports resolution algorithm by strictly following the Node API documentation.
For backwards compatibility a new option `allowExportsFolderMapping` is introduced which will enable deprecated folder mappings.

Test case included

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
@susnux susnux force-pushed the fix/node-resolve-exports branch from 99c413a to 95b7671 Compare August 17, 2023 11:25
@susnux
Copy link
Contributor Author

susnux commented Aug 17, 2023

@lukastaegert @guybedford Thank you very much for your review!
I fixed the sorting as per spec.

Copy link
Member

@lukastaegert lukastaegert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good from my side

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants