[キャッチアップ] pnpm
スクラップの目的
yarn v1 を使用しているプロジェクトを pnpm に移行したい。
関連する他のプロジェクトではすでに pnpm が概ね普及しているため、シナジーを得るためにも pnpm を採用する。
あわせて corepack も使用するようにしたい。
公式ドキュメントがそんなに大きくないので全部読むところからスタート。
pnpm のメリット
- 複数のプロジェクトで同じ依存パッケージを保つ場合に、それぞれのディレクトリにコピーされるのでなく、共通の探索可能なストアに保持されるため、ディスク容量の節約とインストール速度の向上が期待できる
- フラットでない node_modules ディレクトリによって、依存パッケージが依存する別のパッケージに対して直接アクセスできてしまうような問題を解消できる
リポジトリが大量にある組織で、かつ pnpm を採用しているリポジトリが多いほどに効果的っぽい。
依存パッケージが依存する別のパッケージに対して直接アクセスできてしまう
これほんとよくある。必要なパッケージを依存に追加していないはずなのに何故か動くって問題起こりがち。
インストール
これは pnpm 使用してる他のリポジトリのために済んでた。
$ pnpm -v
8.15.3
corepack については別途。
機能の比較
気になったこと
- yarn しか使ってなかったから、 peerDependencies の自動インストールなんて機能が pnpm / npm にあるなんて想像もしてなかった
- Zero-Installs ってなにかと思ったけど、依存パッケージごとコミットしたろうというパワフルな機能らしい
- Node のバージョン管理も pnpm なら出来ちまうってマジ〜?
pnpm CLI
オプションを厳格に検証するよという話。
設定
CLI から設定を作成するやつ。あんまり使わない気がする。rc ファイル作るだろうし。
フィルタリング
CLI コマンドを任意のパッケージに対してのみ実行できるオプション。
使う場面いうほどあるんかな。
らしい
スクリプト
ライフサイクルスクリプト、devPreinstall しかないの…?そんな事ないと思うけど、なんかこの辺ドキュメント雑じゃない?
CLI コマンド 1
この辺は定番。まぁだいたいは npm / yarn と変わらず直感的に乗り換えられそう?
- add
- install
- update
- remove
- run
- dlx
CLI コマンド2
ローカルパッケージを他のプロジェクトから参照できるようにするやつ。あんまりパッケージ開発の経験ないけど、テストするのに使うんだろうな。
- link
- unlink
普通に yarn でもあった。
まれにパッケージ公開してるけど、バージョンアップとかええいままよでリリースしてたわ。
CLI コマンド 3
import で npm/yarn から移行できる。マジ?既存プロジェクトの yarn.lock からバージョンそのままで乗り換えできる?
CLI コマンド 4
rebuild も yarn にあるんだ。といっても v1 にはないみたい。
node_modules 全消ししてからの再インストールとかよくやってたけど、それの代替になるのかな。
CLI コマンド 5
prune ってわざわざ明示的にやらなきゃならんのかな。
yarn だと install 時に同様のことやってくれるから不要らしい。
error The prune command isn't necessary.
yarn install will prune extraneous packages.
CLI コマンド 6
dedupe ありがたいー。yarn v1 だとないから npx yarn-deduplicate
とかいつもやってたのよね。
CLI コマンド 7
patch マジ?そんなことが許されてしまうの?
えぇ…。流石に黒魔術すぎるのではと思ったけど、パッチファイルをコミットすればちゃんとチームで共有もできるってことか。
CLI コマンド 8
audit で脆弱性検知。outdated で更新情報確認。これは renovate や dependabot でよしなに。
list たまに便利だけど全ツリーを眺めるよりは why のほう使う気がする。
licenses あんま眺めたこと無いなぁ。やっちゃいけないことしてしまってる可能性まぁあるな…。
CLI はこんなところかな。他にもコマンドいっぱいあるけど、アプリケーション開発では使う場面限られそうなのでよし。
package.json
package.json 上に記述できる設定。めちゃくちゃたくさんあるのでリファレンス用途で覚えておく。
とはいえ基本的には npm/yarn 互換だし、パッケージ公開用の設定が殆どな気がする。
あと依存パッケージを強引に書き換えるとかそういうハック用途。
yarn v1 → pnpm 移行をやってみる。
最初は個人のポートフォリオサイトあたりでお試ししよう。
import コマンドで yarn.lock から乗り換えられるらしい。
$ pnpm import
WARN 2 deprecated subdependencies found: core-js-pure@3.17.3, stable@0.1.8
Progress: resolved 393, reused 377, downloaded 4, added 0, done
すんなりイケたんかな。
yarn.lock 消して再インストールしてみよ。
$ rm yarn.lock
$ rm -rf node_modules
$ pnpm install
Lockfile is up to date, resolution step is skipped
Packages: +381
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 381, reused 381, downloaded 0, added 381, done
node_modules/.pnpm/@fortawesome+fontawesome-common-types@6.2.0/node_modules/@fortawesome/fontawesome-common-types: Running postinstall script, done in 52ms
node_modules/.pnpm/core-js-pure@3.17.3/node_modules/core-js-pure: Running postinstall script, done in 62ms
node_modules/.pnpm/@fortawesome+fontawesome-svg-core@6.2.0/node_modules/@fortawesome/fontawesome-svg-core: Running postinstall script, done in 50ms
node_modules/.pnpm/@fortawesome+free-solid-svg-icons@6.2.0/node_modules/@fortawesome/free-solid-svg-icons: Running postinstall script, done in 57ms
dependencies:
+ @fortawesome/fontawesome-svg-core 6.2.0
+ @fortawesome/free-solid-svg-icons 6.2.0
+ @fortawesome/react-fontawesome 0.2.0
+ next 12.2.5
+ react 18.2.0
+ react-dom 18.2.0
+ rss-parser 3.12.0
devDependencies:
+ @playwright/test 1.40.1
+ @types/node 20.11.30
+ @types/react 18.0.18
+ autoprefixer 10.4.16
+ babel-plugin-inline-react-svg 2.0.1
+ eslint 8.23.0
+ eslint-config-next 12.2.5
+ postcss 8.4.33
+ prettier 3.2.4
+ prettier-plugin-tailwindcss 0.5.11
+ tailwindcss 3.4.1
+ typescript 4.8.2
Done in 4s
全部 reused になってる。
import した時点でインストールされてて、ストアから node_modules に対してリンク貼っただけってことかな。
開発環境とE2Eテストどっちも通る。もう移行終わったのか…?
$ pnpm dev
$ pnpm e2e
package.json 上でバージョンを定義する。
"engines": {
"node": "20.11.1",
"pnpm": ">=8"
},
vercel 側の設定もちょっと弄ってデプロイを確認。
もう終わっちゃった。
CI 設定とか renovate とかもっと作り込んでるプロジェクトだともう少し手間がかかる気がするので次はそれをやる。