[metro-file-map] On Windows, a relative symlink on another drive than the project resolves under the project's drive, so modules behind it are not found

オープン
#2,138 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 2 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
javascript, node.js

調査の方向性

Start with packages/metro-file-map/src/lib/RootPathUtils.js, especially resolveSymlinkToNormal, and follow how it resolves a relative symlink whose target is on another drive. Run the linked reproduction with the project and store on separate drives; done means npm run bundle writes bundle.js and the resolved module path is on the store's drive.

索引モデルが issue の本文から書いたものです。

説明

Reproduction: https://github.com/YevheniiKotyrlo/metro-file-map-cross-drive-relative-symlink

On Windows, when the project root is on one drive and a watched folder is on another, a relative symlink inside the watched folder resolves to a path under the project's drive (C:\D:\… or D:\C:\…), so every module reached through it fails to resolve. Bun's isolated installs and pnpm lay node_modules out with exactly these relative links, so a project on one drive whose store or monorepo root is on another cannot bundle.

Steps (metro 0.87.2, and metro-file-map built from main at fcced577ad7b1ce8f24a891537f48d326b3a2796; Node 26.12.1, npm 12.2.1, Windows 11):

  1. Clone the reproduction onto one drive and npm install. It is a plain Metro project whose index.js requires greeting, and whose metro.config.js watches the store's node_modules.
  2. node make-store.js C:\Temp\store, a new folder on the other drive. It lays out greeting and punctuation the way Bun's isolated installs do, greeting's dependency on punctuation being the relative symlink ..\..\[email protected]\node_modules\punctuation, and links the project's node_modules/greeting into the store.
  3. npm run bundle, which runs metro build index.js --platform android --out bundle.js.

For main: between steps 1 and 2, yarn install --frozen-lockfile and node scripts/build.js in a react/metro checkout, then node use-metro-main.js <the checkout>, which puts its packages/metro-file-map/build in place of the installed metro-file-map/src.

Expected: bundle.js is written.

Seen, on 0.87.2 and on main alike:

Error: Unable to resolve module punctuation from C:\Temp\metro-store-main-1793405179\node_modules\.store\[email protected]\node_modules\greeting\index.js: punctuation could not be found within the project or in these directories:

With the store on the project's drive (node make-store.js D:\Temp\store in a fresh clone), the same build on main writes bundle.js.

RootPathUtils.resolveSymlinkToNormal (packages/metro-file-map/src/lib/RootPathUtils.js, line 190) resolves the target with path.resolve(this.#rootDir, symlinkNormalPath, '..', readlinkResult). For a symlink on another drive, symlinkNormalPath is the cross-drive normal form, one more .. than the root is deep followed by the drive (..\..\..\..\D:\store\…), which normalToAbsolute understands but path.resolve does not: it clamps the last .. at C:\, giving C:\D:\store\…. With the project root at C:\Users\someone\project:

const utils = new RootPathUtils('C:\\Users\\someone\\project');
const symlink = utils.absoluteToNormal('D:\\store\\node_modules\\.bun\\[email protected]\\node_modules\\invariant');
utils.normalToAbsolute(utils.resolveSymlinkToNormal(symlink, '..\\..\\[email protected]\\node_modules\\invariant'));
// 'C:\\D:\\store\\node_modules\\.bun\\[email protected]\\node_modules\\invariant'

Resolving from this.normalToAbsolute(symlinkNormalPath) instead of joining the normal path onto the root gives D:\store\node_modules\.bun\[email protected]\node_modules\invariant. #1696 makes normalToAbsolute return an absolute normal path as it is, which does not reach this case, since the stored normal path is relative.

主要言語
JavaScript
スター
5.7k
フォーク
711
平均マージ
2日 18時間
マージ済み PR(30日)
66

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

react/metro のほかの issue

react/metro の issue をすべて見る

似ている issue

JavaScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。