📚

モノレポで重複する依存関係を楽に管理するpnpmカタログ

2024/09/17に公開

pnpm catalogとは

pnpm v9.5.0でリリースされたpnpmワークスペース向けの機能

https://pnpm.io/ja/catalogs

https://github.com/pnpm/rfcs/pull/1

pnpmワークスペースにおいて、複数のパッケージで共通して使用するライブラリのバージョンを統一できる

monorepoでは特にReactや主要ライブラリのバージョンが異なると困ることがあるので、t3-turboでも採用された

https://github.com/t3-oss/create-t3-turbo/pull/1081

usage

カタログはcatalog:catalogs: で生成できる

  • catalog:

    defaultという名前のカタログを生成する。

  • catalogs:

    任意の名前のカタログを生成する

catalog:

defaultという名前のカタログを生成する

pnpm-workspace.ymlに以下のように共通化したいライブラリのバージョン範囲を指定する

packages:
  - packages/*

catalog:
  eslint: ^9.9.0
  prettier: ^3.3.3
  tailwindcss: ^3.4.10
  typescript: ^5.5.4

これを各パッケージのpackage.jsonで

{
  "name": "@example/app",
  "dependencies": {
    "eslint": "catalog:", # equivalent to ^9.9.0
    "typescript": "catalog:" # equivalent to ^5.5.4
  }
}

のように指定できる。バージョンを変数化して再利用できるということ

後述するがpackage.jsoncatalog:を指定するとデフォルトのカタログが使用される

catalogs:

任意の名前のカタログを生成する

catalogs:
  react18:
    react: 18.3.1
    react-dom: 18.3.1
    "@types/react": ^18.3.3
    "@types/react-dom": ^18.3.0

任意のカタログ名のカタログをpackage.jsonで使用する時はカタログ名を指定する

    "react": "catalog:react18",
    "react-dom": "catalog:react18",

package.jsonでのカタログの指定

  • catalog:のみだと、デフォルトのカタログ(pnpm-workspace.ymlcatalog:で指定されたバージョン)を使用する
  • catalog:catalogNameとすると、特定のカタログ名をもつカタログを使用する
packages:
  - packages/*

catalog:
  next-auth: 5.0.0-beta.20

catalogs:
  next-auth-4:
    next-auth: ^4.24.7
"next-auth": "catalog:" # 5.0.0-beta.20
"next-auth": "catalog:next-auth-4" # ^4.24.7

メリット

  • 複数のパッケージで共通して使用するライブラリのバージョンが異なることがなくなる
  • ライブラリのバージョンを更新する際もpnpm-workspace.ymlを更新するだけでよく、コンフリクトも起きづらい
  • パッケージが重複することで発生する無駄なバンドルサイズの増加を無くせる

Discussion