pnpmで意図しないpeer dependenciesがあり問題が起こるときの対処
※この情報はpnpm@9時点での情報です
tl;dr
pnpm i --resolution-onlypnpm i --fix-lockfile
peer dependenciesで問題が起こったら、どちらかを実行する。
pnpmを使っているプロジェクトで、node_modulesの中に不必要なモジュール(optional peer dependencies)がずっと入っていたりする問題がある。
このことで普通はそんなに問題は起こらないが、稀に問題を引き起こすことがある。
昔入ってしまったpeer dependenciesがnode_modules内に存在することで
こういったことが起こる。
import.meta.resolveでモジュールがあると誤検知してしまう- 入れた覚えも入っている前提でもないのに、たしかにいる!
- TSが型解決するときにpeerのバージョンを先に見つけて古い型を使うことでエラーになる
少なくとも自分が観測した事例だと以下のようなことがあった。
- storybookをセットアップすると
lesssasssugarcssなどが入っている - viteのプラグインを入れると
rollup@2rollup@3など過去のバージョンが入っている- プロジェクト環境では
rollup@4を期待するが、TSがrollup@3を見に行きプラグインが型エラーになる
- プロジェクト環境では
ちなみに
前提としてこの問題はpnpmの hoist と auto-install-peers をenableにしていると発生するはず。
両者とも.npmrcで設定しない限りデフォルトではtrue。
peer dependenciesを整理整頓する
pnpmは通常の pnpm install では一度ロックファイルに書き込まれたpeer dependenciesのバージョンは更新しない(これはpnpmではfull resolutionという概念らしい)。そしてpnpm-lock.yamlに書かれている以上は、そのバージョンのそのモジュールがインストールされてしまう。
トレードオフとして、pnpm-lock.yamlに書き込まれた「昔入れたモジュールに付随していたpeer dependenciesが更新されていない」ということが発生する。
というわけで、full resolutionする
以下のどちらかをすればよい。そしてロックファイルが更新されたあとにもう一度 pnpm iを実行して node_modules を更新する。
pnpm i --resolution-onlypnpm i --fix-lockfile
これでlockファイルがメンテされ、このエントリで言っている問題を回避できるようになる(可能性がある)。
※なおpnpmのソースコードはこのあたり