yarn v1 から pnpm への移行でより高速で安全に
AI Shift には yarn v1 を使って管理しているフロントエンドのモノレポがありました。しかし、インストールが遅かったり、yarn v1が2020年からメンテナンスモードでいつEOLになってもおかしくない状況なので、yarn をバージョンアップするか、npm か pnpm に乗り換える必要がありました。
技術選定
まず yarn のバージョンアップを考えましたが、yarn はv2から node_modules
を使わないPnP方式を採用していて、対応していないライブラリがあったり、PnP採用に関する情報が少なかったりと不安材料が多かったので今回は yarn を採用しないことにしました。
そうなると npm か pnpm のどちらかになります。pnpm のメリットとして package.json に書いてあるパッケージのみimportを許容する厳格性があります。 npm, yarn では深い依存を含めたすべてのライブラリが node_modules
に格納されます。その結果、開発コードは package.json に書かれていない依存ライブラリにアクセスできてしまいます。
私たちのフロントエンドは巨大で多くのライブラリに依存しているので、この厳格性は大きなメリットだと感じました。
さらに pnpm v9.5 で追加されたパッケージでバージョンを揃えられるcatalog機能にも惹かれて pnpmを採用することにしました。
pnpm の環境構築
移行当初、pnpm の管理は corepack でやろうと思っていました。しかし、corepack が Node.js から分離 されることになりました。corepack が Node.js から分離されるのであれば、あえて corepack を使う必要はなくなります。
そんな中、pnpm 9.7 から package.json の packageManager に pnpm のバージョンを指定できるようになりました。 これによってチームメンバーのローカル環境、CI環境でpnpmのバージョンを揃えることができます。
この機能が出る前までは volta でバージョンを揃えていましたが、volta だと、(volta を CI に入れない限り)CI のバージョンまでは揃えられないので pnpm のこの機能は大変ありがたいです。
pnpm でパッケージをインストール
pnpm には pnpm imoprt
というコマンドがあり、これを用いることで移行前のロックファイルから必要なパッケージをインストールすることができます。
pnpm import yarn.lock
pnpm i --frozen-lockfile
追加で必要なパッケージをインストールする
基本は pnpm import
で大丈夫なのですが、一部のパッケージが not found になってしまいました。
これは、yarn v1 では直接 package.json に書かれていないパッケージでも、使用しているパッケージが内部で使用していれば import できてしまうからです。つまり今まで暗黙的に import していたパッケージを package.json
に明記してインストールする必要があります。
このような暗黙的な import がなければ pnpm import
だけでも動作するのですが、残念ながらそうはいかず、いくつか追加でインストールする必要がありました。この作業は面倒ではありますが、今までがむしろ危険な状態で、この機会により安全にパッケージを管理できるようになったということでもあります。
pnpm catalog
この機能のために移行したと言っても過言ではありません。詳しい説明は省略しますが、これを用いると異なる workspace のパッケージ間で共通のバージョンを使用することができます。
例えば、packages/a
と pacakges/b
が両方とも react を使っていた場合、今までは両方のpackages.json
に react
のバージョンを書いていました。これらのバージョンは揃えたい場合、バージョンアップのときに両方の package.json
を更新する必要があります。catalog 機能を使えばバージョンをトッププレイヤーで宣言して各 package.json
はそれを参照する形になるので、明確にバージョンを揃えることができます。
当然、バージョンの共通化には段階的にアップデートできなくなるなどのデメリットもあるので、共通のパッケージをすべて catalog で管理するわけではなく、運用上同一バージョンになっているべきパッケージのみをcatalogで管理するようにしています。
pnpm patch
パッチを当てて管理していたパッケージがあるので、それを pnpm patch
で管理するようにしました。今まではpatch-packageを使って管理ししていました。
今までの使用していたパッチファイルを削除して、pnpm patch
で新規にパッチを作成するだけで簡単に移行できました。パッチの管理をパッケージマネージャに任せられるようになったのありがたいです。
CI で pnpm のセットアップ
AI Shift では CI に GitHub Actions を使用しています。pnpm 公式が GitHub Actions 用のアクションを用意してくれているのでそれを使えば問題ないと思います。corepack を使う方法もありますが、前述の通り corepack は使用しない方針にしたので CI でも使いません。
pnpm setup action は jobのyamlファイルに pnpm のバージョンを指定するか、package.json
のpackageManager
フィールドのどちらかでバージョンを指定できます。ローカルとのバージョンを揃えたいので基本的には packageManger
に指定する形で良いかなと思います。
まとめ
corepack が Node.js から外されることもあり、pnpm の管理については少し悩みましたが、yarn から pnpm への移行自体はそこまで大変ではありませんでした。移行後はインストールが高速になり、パッケージのバージョンも安全に管理できるようにうになりました。pnpm は今も便利な機能が追加されているので、今後もリリース情報を追ってうまく活用していきたいと思います。
最後に
AI Shiftではエンジニアの採用に力を入れています!
少しでも興味を持っていただけましたら、カジュアル面談でお話しませんか?
(オンライン・19時以降の面談も可能です!)
【面談フォームはこちら】
Discussion