Site cover image
pnpm workspace で public-hoist-pattern が必要になることがある理由

Turborepo のドキュメントで、prisma を package 化するときに .npmrc に以下の行の追加が必要という記載がある。

public-hoist-pattern[]=*prisma*

実際、これを追加しないと Cannot find module と怒られてしまう。

これはなぜ必要なのか、理解ができていなかったので調べてみた。

これを理解するためには pnpm workspace の仕組みを理解することが必要。

pnpm は node_modules において、ネスト構造を採用している。

  • package.json の dependencies に記載されたパッケージ(foo)は、node_modules 配下にディレクトリが作成される
    • このディレクトリは シンボリックリンクになっており、 node_modules/.pnpm に実体がある
  • foo が依存している bar は、 node_modules/.pnpm/foo@1.0.0/node_modules 配下にディレクトリが作成される
    • このディレクトリも node_modules/foo 同様、シンボリックリンクになっており、 node_modules/.pnpm に実体がある
node_modules
├── foo -> ./.pnpm/foo@1.0.0/node_modules/foo
└── .pnpm
    ├── bar@1.0.0
    │   └── node_modules
    │       └── bar -> <store>/bar
    └── foo@1.0.0
        └── node_modules
            ├── foo -> <store>/foo
            └── bar -> ../../bar@1.0.0/node_modules/bar

引用: シンボリックリンクを使用した `node_modules` の構造

npm(v3以降) や yarn では、全て node_modules 直下にディレクトリが作成されるため、dependencies に記載されていない依存パッケージも読み込めてしまう。という問題がある。

pnpm の採用しているネスト構造は、この問題を解決するものとなっている。

つまり、pnpm では、dependencies に直接書いているパッケージしか読み込めないという制約が存在している。

Turborepo の例では、prisma をパッケージに閉じ込めているので、読み込み元からは prisma を直接呼び出せなくなる。

public-hoist-pattern に記載することでnode_modules 直下にディレクトリが巻き上げ(hoisting)され、直接読み込むことができるようになる。

Thank you!
Thank you!
URLをコピーしました

コメントを送る

コメントはブログオーナーのみ閲覧できます