Skip to content

Move package-relative path calculation under context.getPackageForModule#1268

Closed
robhogan wants to merge 2 commits into
react:mainfrom
robhogan:export-D56823091
Closed

Move package-relative path calculation under context.getPackageForModule#1268
robhogan wants to merge 2 commits into
react:mainfrom
robhogan:export-D56823091

Conversation

@robhogan

@robhogan robhogan commented May 2, 2024

Copy link
Copy Markdown
Contributor

Summary:
During resolution using package.json#exports or the browser spec, we need package-relative subpaths of resolution candidates to check against these export/redirect maps.

Currently, we derive these using (pseudo code):

const absolutePathOfPackageRoot = context.getPackageForModule(absolutePathOfCandidate).rootPath;
const packageRelativePath = path.relative(absolutePathOfPackageRoot, absolutePathOfCandidate);

However, this implicitly assumes that both paths are either real, or traverse the same set of symlinks, so that the former is a prefix of the latter. If getPackageForModule returned rootPath: fs.realpath(packageRoot), this assumption would not hold.

Eg: if /workspace-root/pgk-a/foo.js imports pkg-b/bar.js, we will try a candidate /workspace-root/node_modules/pkg-b/bar.js, but node_modles/pkg-b may be a symlink to /workspace-root/pkg-b, and path.relative(realPackageRoot, candidate) will give ../node_modules/pkg-b/bar.js, which will not match against an export map, though it represents the same location on the filesystem.

Instead, we move the calculation of packageRelativePath inside getPackageForModule and close to implementation of the package search, where we know that the path.relative call is safe under the current implementation, and allowing an alternative implementation to use an alternative mechanism.

This is in preparation for a new implementation of getClosestPackage, which currently dominates resolution time, using FileSystem, which will natively return only real paths.

Differential Revision: D56823091

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 2, 2024
@facebook-github-bot

Copy link
Copy Markdown
Contributor

This pull request was exported from Phabricator. Differential Revision: D56823091

@robhogan robhogan marked this pull request as draft May 2, 2024 13:45
robhogan added 2 commits June 2, 2024 12:06
Summary:
This is a simple relabelling to make clear when resolution-related methods expect *absolute* paths, as opposed to origin-relative, package-relative or bare specifiers that are present under the name `modulePath`. It should make the next diffs a little easier to reason about.

Changelog: Internal

Differential Revision: D56788884
…dule` (react#1268)

Summary:

During resolution using `package.json#exports` or the `browser` spec, we need package-relative subpaths of resolution candidates to check against these export/redirect maps.

Currently, we derive these using (pseudo code):
```
const absolutePathOfPackageRoot = context.getPackageForModule(absolutePathOfCandidate).rootPath;
const packageRelativePath = path.relative(absolutePathOfPackageRoot, absolutePathOfCandidate);
```

However, this implicitly assumes that both paths are either real, or traverse the same set of symlinks, so that the former is a prefix of the latter. If `getPackageForModule` returned `rootPath: fs.realpath(packageRoot)`, this assumption would not hold.

Eg: if `/workspace-root/pgk-a/foo.js` imports `pkg-b/bar.js`, we will try a candidate `/workspace-root/node_modules/pkg-b/bar.js`, but `node_modles/pkg-b` may be a symlink to `/workspace-root/pkg-b`, and `path.relative(realPackageRoot, candidate)` will give `../node_modules/pkg-b/bar.js`, which will not match against an export map, though it represents the same location on the filesystem.

Instead, we move the calculation of `packageRelativePath` inside `getPackageForModule` and close to implementation of the package search, where we know that the `path.relative` call is safe under the current implementation, and allowing an alternative implementation to use an alternative mechanism.

This is in preparation for a new implementation of `getClosestPackage`, which currently dominates resolution time, using `FileSystem`, which will natively return only *real* paths.

Changelog: Internal

Differential Revision: D56823091
@robhogan robhogan force-pushed the export-D56823091 branch from 248951b to 9707689 Compare June 2, 2024 19:07
@facebook-github-bot

Copy link
Copy Markdown
Contributor

This pull request was exported from Phabricator. Differential Revision: D56823091

@facebook-github-bot

Copy link
Copy Markdown
Contributor

This pull request has been merged in e303578.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants