Resolver: Remaining differences from Node in `"exports"` resolution
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 42/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- javascript
調査の方向性
Start in packages/metro-resolver/src/PackageExportsResolve.js, packages/metro-resolver/src/utils/matchSubpathPattern.js, packages/metro-resolver/src/utils/matchSubpathFromExportsLike.js, and packages/metro-file-map/src/lib/TreeFS.js, then compare the listed cases against Node’s require.resolve. The issue identifies several concrete mismatches, but does not name tests to run. Done means the applicable cases produce Node-compatible resolution results or Metro resolution errors instead of raw exceptions or silent incorrect resolutions.
索引モデルが issue の本文から書いたものです。
説明
With #2160, Metro follows Node's PACKAGE_RESOLVE for which package.json and subpath to use with "exports". A comparison with Node (AI-driven, against require.resolve on Node 26, and on Node 24 for Windows) found these remaining differences. Unless noted, they reproduce with resolver.unstable_resolveExportsFromPackageRoot on or off, so they aren't new with that flag.
I've left out Metro's warn-and-fall-back for unexported subpaths and invalid configs, which is intentional for now, and pkg/ resolving as pkg where there's a "." entry (Node says not exported), which we're keeping because require('x/') is a common idiom.
None of these look common. I'd start with the TypeErrors, since those fail on packages that work in Node.
Metro fails where Node resolves
| Case | Specifier | Node | Metro | Code |
|---|---|---|---|---|
"exports": false (or true, 1), with "main": "m.js" |
pkg |
m.js |
Raw TypeError |
Non-object WeakMap key |
package.json is a symlink to store/manifest.json, with "exports": {".": "./root.js"} and root.js beside the symlink |
pkg |
node_modules/pkg/root.js |
Warns about a missing file, fails to resolve | Targets are relative to the manifest's real directory |
No "exports", "main": "lib/m.js" |
pkg/. |
lib/m.js |
Raw Error: Unexpectedly escaped traversal |
TreeFS invariant |
No root package.json, sub/package.json has "main" |
pkg//sub |
sub/main.js |
Fails to resolve | |
missing doesn't exist, or @m has no package |
missing/../pkg/a.js, @m/../pkg/a.js |
pkg/a.js under require |
Fails to resolve |
pkg/. also throws that raw Error for a package with "exports". Node rejects those too, but we should fail with a resolution error.
Metro resolves where Node rejects
These are silent, with no warning.
| Case | Specifier | Node | Metro | Code |
|---|---|---|---|---|
"exports": {"./lib*": "./dist/lib*.js"} |
pkg/lib |
ERR_PACKAGE_PATH_NOT_EXPORTED |
dist/lib.js |
No length check without a trailer |
"exports": {"./a/": "./ok.js"} |
pkg/a/ |
ERR_PACKAGE_PATH_NOT_EXPORTED |
ok.js |
Exact match on a key ending in / |
"exports": {"./a": "./NODE_MODULES/a.js"} |
pkg/a |
ERR_INVALID_PACKAGE_TARGET |
NODE_MODULES/a.js |
Case-sensitive segment check |
"exports": {"./a": {"0": "./x.js", "default": "./y.js"}} |
pkg/a |
ERR_INVALID_PACKAGE_CONFIG |
y.js |
Numeric condition keys aren't rejected |
"exports": {"./a": "./x.js", "#b": "./y.js"} |
pkg/a |
ERR_INVALID_PACKAGE_CONFIG |
x.js |
# keys count as subpaths |
Other
- Percent-encoding: Node decodes
pkg/%2e%2e/secret.jsand throwsERR_INVALID_MODULE_SPECIFIER, and it rejects a target like./%2e%2e/b.jswithERR_INVALID_PACKAGE_TARGET. Metro treats these as literal paths, so they warn about a missing file and then fall back. They can't escape the package. - Windows: With
"exports": {"./shim": "./dist/shim.js"}and a nestedshim/package.json,require('pkg\\shim')in Node gets the nested package'smain, ignoring"exports". With the flag on, Metro normalises the backslash, so it getsdist/shim.js. I've only confirmed Metro's side of this one from a review run and the code. - POSIX backslashes: With
"exports": {"./f": "./lib\\f.js"}, Node resolveslib/f.json any platform. Metro on macOS and Linux treats the backslash literally, so it warns about a missing file. Windows matches Node. - Windows trailing slashes: With a target like
"./a.js/"or"./img.png/", Node 24 on Windows resolves the file. Metro warns and fails on every platform, matching Node on POSIX. - Pattern matches with the flag off: With
"exports": {"./p/*": "./lib/*"}and the flag off,pkg/p/g/../f.jsandpkg/p/g/node_modules/h.jsresolve where Node throwsERR_INVALID_MODULE_SPECIFIER. Enablingresolver.unstable_resolveExportsFromPackageRootfixes this.
Fixed
- #2089: Fallback arrays in
"exports"and"imports"are tried in order, including[{"never": "./dist/y.never.js"}, "./dist/y.js"],["not-valid", "./dist/x.js"]and[null, "./dist/n.js"]. - #2089: Targets with an empty segment, such as
"./dist//c.js", resolve.
- 主要言語
- JavaScript
- スター
- 5.7k
- フォーク
- 715
- 平均マージ
- 3日 14時間
- マージ済み PR(30日)
- 77
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
react/metro のほかの issue
-
[metro-file-map] An error a watcher backend reports ends the server, since nothing listens for it対応中かも @sorinc03 が 3 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
Resolver: Read `exports` from the package root, not the closest `package.json`対応中かも @robhogan が今日担当しました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 22/100
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
メンテナーはふだん 1 日以内に返信
-
metro-file-map gives up on a fallback watcher that is still starting after a fixed 240 s, and leaves it running対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
メンテナーはふだん 1 日以内に返信
-
Published declarations import types from connect, @babel/core and @babel/traverse, whose @types packages are not dependencies対応中かも @sorinc03 が 3 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
parse-community/parse-server#10871 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Jump in core size from v2.11.2対応中かも @caolan-tether が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
holepunchto/hyperbee2#126 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
521xueweihan/HelloGitHub#4270 ·
-
Adopt browserslistrcオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
accessibility bug embed
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
quarto-dev/quarto-cli#15306 ·
メンテナーはふだん 1 日以内に返信