😊

Yarn v1(Yarn Classic)をpnpmに移行する手順

2024/07/11に公開

Yarn v1(Yarn Classic)からpnpmに移行する機会がよくあるため手順をまとめました。
※ 執筆時(2024.7)の情報になるため、古くなる可能性があります

パッケージマネージャー設定の変換

以下のコマンドを実行します。

npx @turbo/workspaces convert

これはTurborepoが提供しているパッケージマネージャー変換ツールです。
https://github.com/vercel/turbo/tree/main/packages/turbo-workspaces

プロンプトに従って、「pnpm」を選択します。

pnpm-lock.yamlpnpm-workspace.yamlなど必要なファイルが作成されます。

シンプルなリポジトリであればこれで完了します。
以下は特別な設定をしている場合の移行と修正になります。

Yarn設定の移行

Yarnの機能(resolutionsなど)を使っている場合はpnpm用に置き換えます。

こちらの記事が詳しいです。
https://zenn.dev/kkoudev/articles/117d6724f78586#yarn独自の記述を置き換える

設定を変えた場合、pnpm iで再度ロックファイルを生成します。

依存漏れの修正

pnpmではpackage.jsonのdependencies, devDependenciesに書かれた直接依存のみnode_modules直下に展開され解決可能になります。
(依存の依存はnode_modules/.pnpmに置かれる)

Yarn v1ではたまたま解決できた、というケースがよくあるので、ビルドやtscなどでエラーになった場合は適宜dependencies, devDependenciesに追記します。

peer依存のオプション

Yarn v1では依存ライブラリに記載されているpeerDependenciesは自動ではインストールしませんが、pnpmはoptionalではないpeerDependenciesを自動でインストールします。[1]
see. https://pnpm.io/ja/npmrc#auto-install-peers

稀ではありますが、古いライブラリだとインストールされる前提ではないpeerDependenciesをoptionalにせずに記載していることがあり、これが不具合を起こすケースがあります。

この場合ライブラリ側を直すのが筋ですが、そもそもこういった記述になっているライブラリは古くメンテナンスされてないケースも多いため、使用する側で対処することも出来ます。

package.json
{
  "pnpm": {
    "packageExtensions": {
      "@example/react-utils": {
        "peerDependenciesMeta": {
          "react": {
            "optional": true
          }
        }
      }
    }
  }
}

see. https://pnpm.io/ja/package_json#pnpmpackageextensions

pnpm移行後のpnpmインストール手順について

変換ツールを使用すると、package.jsonのpackageManagerに使用しているpnpmのバージョンが追記されます。

package.json
  "packageManager": "pnpm@9.0.0+sha224.953c..(省略)"

see. https://github.com/nodejs/corepack?tab=readme-ov-file#when-authoring-packages

v16.9.0以降のNode.jsを使っていればcorepackがインストールされているため、開発者のローカルマシンやCIでは以下のコマンドを打てば記載されているパッケージマネージャーを使用出来ます。

corepack enable pnpm

pnpm -v
#=> 9.0.0
脚注
  1. なお、pnpm v7以前はauto-install-peersはデフォルトでfalseなので、自動インストールしません ↩︎

Discussion