pnpmで特定パッケージだけビルドキャッシュの再利用を除外する

pnpmで特定パッケージだけビルドキャッシュの再利用を除外する

pnpm 12.14.0のsideEffectsCache.excludeを使うと、指定したパッケージだけビルド結果のキャッシュ再利用を除外できます。ローカルのサンプルで通常時と除外時の再インストールを比較し、設定方法と既存キャッシュが残る点を紹介します。
2026.10.23

どうも!オペ部の西村祐二です!

システムの共有ライブラリに依存するパッケージでは、パッケージのバージョンが同じでもビルド結果を使い回したくない場合があります。pnpmの12.14.0で追加されたsideEffectsCache.excludeを使うと、指定したパッケージだけビルド結果のキャッシュ再利用から外せます。

除外するパッケージ名を指定する

pnpm 12.14.0以降では、プロジェクト直下のpnpm-workspace.yamlに次の設定を書きます。cache-demo-addonは、後半で使うサンプルのパッケージ名です。実際の利用時は、除外したい依存パッケージ名を指定します。

pnpm-workspace.yaml
sideEffectsCache:
  exclude:
    - cache-demo-addon

この指定だけで、他のパッケージのside-effects cacheの読み書きは既定の有効状態を保ちます。設定後のインストールは、通常どおりです。

pnpm install

対象パッケージは、ローカル・リモートのside-effects cacheからビルド結果を復元せず、保存もしません。ダウンロードしたパッケージ本体のキャッシュを無効にする設定ではありません。また、ビルドスクリプトの実行許可は別に必要です。既存のnode_modulesがある状態での再ビルドまでは、この記事では確認していません。以下ではnode_modulesを削除して比較します。

同じ依存を入れ直して比較する

Ubuntu 24.04.5 / Linux arm64、Node.js 24.21.0、pnpm 12.14.0で確認しました。ネイティブモジュールのコンパイルの代わりに、環境変数の値をファイルに書くpostinstallを使い、ビルドが再実行されたかを見ます。

1. ビルド結果を残すパッケージを用意する

pnpm 12.14.0とNode.jsが使える環境で、新しいサンプル用ディレクトリを作ります。

mkdir pnpm-cache-demo
cd pnpm-cache-demo
mkdir package
cd package

package内に次の2ファイルを保存します。

package/package.json
{"name":"cache-demo-addon","version":"1.0.0","scripts":{"postinstall":"node build.cjs"}}
package/build.cjs
const fs = require('node:fs');
fs.writeFileSync('built.txt', process.env.BUILD_MARKER || 'unset');

パッケージをtarballにして、サンプルのルートへ戻ります。

pnpm pack --pack-destination ..
cd ..

2. キャッシュを有効にした状態で入れ直す

ルートに次の2ファイルを保存します。ビルド許可には、今回のfile:依存を表すキーを指定しています。

package.json
{"name":"cache-demo-app","version":"1.0.0","private":true,"dependencies":{"cache-demo-addon":"file:cache-demo-addon-1.0.0.tgz"}}
pnpm-workspace.yaml
storeDir: .pnpm-store
updateNotifier: false
enableGlobalVirtualStore: false
permissions:
  cache-demo-addon@file:cache-demo-addon-1.0.0.tgz:
    build: true

この例ではサンプル専用のstoreを使い、global virtual storeを無効にして比較条件をそろえます。以下のrm -rf node_modulesは、この新規サンプル内の依存を入れ直すための操作です。

BUILD_MARKER=first pnpm install
cat node_modules/cache-demo-addon/built.txt
rm -rf node_modules
BUILD_MARKER=second pnpm install --frozen-lockfile
cat node_modules/cache-demo-addon/built.txt

どちらもfirstになりました。2回目は環境変数をsecondに変えても、最初のビルド結果がキャッシュから復元されています。

3. 除外設定を追加して入れ直す

先ほどのpnpm-workspace.yamlの末尾に、冒頭のsideEffectsCacheブロックを追加します。既存のビルド許可は残します。

rm -rf node_modules
BUILD_MARKER=third pnpm install --frozen-lockfile
cat node_modules/cache-demo-addon/built.txt
rm -rf node_modules
BUILD_MARKER=fourth pnpm install --frozen-lockfile
cat node_modules/cache-demo-addon/built.txt

今度は順にthird、fourthになりました。同じtarballを使ったまま、それぞれのインストールでpostinstallが実行されています。

次の画像は比較結果をファイルに記録し、ターミナルに表示したものです。最後の行は、除外設定を外してもう一度入れ直した追加確認です。

通常はfirstを再利用し、除外時はthirdとfourthでビルドし直す比較結果

除外を解除すると古いキャッシュが再利用される

sideEffectsCacheブロックを削除し、ビルド許可などは残したまま、もう一度入れ直します。

rm -rf node_modules
BUILD_MARKER=fifth pnpm install --frozen-lockfile
cat node_modules/cache-demo-addon/built.txt

結果はfirstに戻りました。除外中に作ったthirdやfourthではなく、除外前のキャッシュが残っていました。

この設定はキャッシュの読み書きを省くためのもので、既存のビルドキャッシュを削除する操作ではありません。除外対象を戻すときは、この違いを踏まえる必要があります。

公式ドキュメントでは、名前のほかに@scope/*や、完全一致バージョンを付けた指定も案内されています。今回は名前だけを指定した、ローカルtarball依存の動作に絞りました。リモートキャッシュ、global virtual storeでのプロジェクト間共有、実際のネイティブモジュール、macOS・Windowsでの動作は検証対象に含めていません。

まとめ

pnpmのsideEffectsCache.excludeにパッケージ名を書くと、その依存を、ビルド結果のキャッシュ再利用の対象から外せました。共有ライブラリなど、キャッシュキーに含まれない条件がビルド結果を左右するパッケージに使う設定です。既存キャッシュの削除や、ビルドスクリプトの実行許可とは役割が異なります。

参考リンク:

この記事をシェアする

関連記事