yarn v4からpnpmに移行した
2025/09 中旬、npm のサプライチェーン攻撃が結構大変なことになっています。
これさえすれば。という対策方法はないようですが一つのプラクティスとして pnpm の各機能が注目されていたので、このブログのビルドも pnpm へ移行しました。
背景
- https://www.trendmicro.com/ja_jp/research/25/i/npm-supply-chain-attack.html
- https://zenn.dev/nix/articles/0a2910ec65b4a3
色々な情報を見ていると、この手の攻撃はnpm install
実行時のpostinstall
で悪意のある js が実行されることが一つ大きな問題のようです。
pnpm の利点
pnpm
は v10 あたりから依存パッケージによるスクリプト実行をデフォルトでブロックするようになっています。
許可する場合は特別にpnpm approve-builds
コマンドで許可パッケージを指定します。
http://pnpm.io/ja/cli/approve-builds
移行作業
1. pnpm のインストール
今回はmise
を利用しました。
node
やらpython
やらをいろんなツールでバージョン管理するのは面倒なので、最近mise
に寄せています。
mise use -g npm:pnpm
package.json
の更新
2. package.json
にフィールドを追加します。
https://pnpm.io/ja/settings#managepackagemanagerversions
{
"packageManager": "[email protected]"
}
ここを読んで自動で対応バージョンのpnpm
を使ってくれたりする CI ツールの実装もあるみたいです。
3. lock ファイルの以降
yarn.lock
からpnpm-lock.yaml
を生成します。
公式のコマンドがあります。
pnpm import yarn.lock
4. 依存パッケージのインストール
yarn v4 では Yarn Plug'n'Play を利用しており、node_modules
はありませんでした。
http://yarnpkg.com/features/pnp
pnpm はnode_modules
を生成して依存解決を行うので、あらためて依存関係をインストールします。
pnpm install
5. yarn 関連のファイル削除
yarn 関連のファイルを削除します。
特に PnP 関連のファイルが残っているとうまく依存解決できなかったりするので、忘れず消しましょう。
rm -rf ./.yarn/ ./yarn.lock ./.pnp.cjs ./.pnp.loader.mjs
6. デプロイ関係の書き換え
現在このブログは Cloudflare Pages でデプロイされているので、デプロイ設定を書き換えます。
以下の書き換えを実施しました。
ビルドコマンド:yarn build
→pnpm build
環境変数:YARN_VERSION
→PNPM_VERSION
まとめ
上記作業は 1 時間もかからずできました。
pnpm は依存パッケージの依存からimport
がある場合にエラーとなるので、そういった隠れ依存がコードにあると移行手順が増えますが、今回はなくてよかったです。
仕事でも移行をしていますが、そちらでは CI の設定ファイル修正でキャッシュの扱いに少しハマりました。Cloudflare の楽ちんデプロイに感謝。