iOS&Androidスマートフォン開発(Swift/Kotlin/React-Native) および Next.js/LaravelをはじめとしたWeb開発ならば、ぜひ創業13年の弊社にお任せください。ワンストップでお届けします。お問合せはこちらから

参照ゼロのpuppeteerが毎ビルドChromiumを落としていた。使っていない依存の棚卸しをした話

  2026年09月14日 11:50 / - PV

yuku_tasのアイコン

こんにちは、Webサービス開発者のyuku_tasです。

簡単なプロフィール: MoldSpoon Inc.代表。開業から15年、業界に携わって20年。Webサイト/iOS/Androidアプリ開発から、データ分析業務・コンサル業務、ベンチャーから保険会社まで様々な案件を個人会社の形で請け負ってまいりました。詳しくはこちら

はじめに

ビルドが落ちたのをきっかけにpackage.jsonを眺めていて、見覚えのないパッケージが目に入りました。

"puppeteer": "^21.2.1",

使っている記憶がありません。

調べたら本当に使っていませんでした。それどころか、この1行のせいで毎回のビルドでChromiumがダウンロードされていました。170MB前後です。何にも使われないまま、毎回。

同じような残骸を抱えているプロジェクトは多いと思うので、洗い出し方と、消すときの確認手順を書いておきます。

なぜ「使っていない依存」が害になるのか

使っていないだけなら、バンドルには入りません。Next.jsはimportされていないコードを出力に含めないからです。なのに害があります。

理由は主に3つです。

  • postinstallでバイナリを落とすパッケージがある(puppeteer、かつてのnode-sassなど)
  • ネイティブビルドを走らせるパッケージがある(Nodeを上げた瞬間に壊れる)
  • 依存ツリーが膨らみ、インストールとキャッシュが重くなる

とくに1つ目と2つ目は、コードが1行も触れていなくても、インストールの時点で動くのがポイントです。「使っていないから無害」は成り立ちません。

うちは2つ目でビルドが落ちました。使っていないパッケージが原因で本番のデプロイが止まる、というのはなかなか間抜けな話です。

洗い出し方

1. 参照をimportの形で検索する

パッケージ名で全文検索すると、関係ない単語が大量に引っかかります。 importの形で探すのが確実です。

PKG=puppeteer
grep -rn "from '$PKG'\|from \"$PKG\"\|require('$PKG')\|require(\"$PKG\")\|from '$PKG/" \
  --include=*.ts --include=*.tsx --include=*.js --include=*.jsx --include=*.mjs \
  . | grep -v node_modules

うちのcanvasがまさにこれで、単語で検索するとBusinessModelCanvasやhtml2canvas、<canvas>要素が山ほど出て「使っている」と誤認しかけました。

2. 設定ファイルからの参照も見る

コードだけでなく、設定ファイルから名前で参照されるものがあります。

  • ESLint / Prettier のプラグイン
  • PostCSS / Tailwind のプラグイン
  • Jest / Playwright などの設定
  • package.jsonのscripts(CLIとして直接叩いているもの)
grep -rn "puppeteer" package.json *.config.* .*rc* 2>/dev/null

「importされていない=使っていない」ではないのはこの層です。ここを見ずに消すと、CIだけが後から壊れます。

3. 誰かの依存になっていないか確認する

自分が使っていなくても、他のパッケージが依存していることがあります。yarnならこれで分かります。

yarn why puppeteer

「他のパッケージが必要としている」と出たら、package.jsonから消してもnode_modulesには残ります。それでも直接依存から外す意味はあります。 バージョンを自分で固定しなくなるので、依存元の更新に追随できるようになります。

うちのcanvasはyarn.lockを見ても依存元が存在しない残骸でした。おそらく昔なにかを試した名残です。

消したあとの確認

消して終わりにせず、ビルドを通してからコミットします。

rm -rf node_modules
yarn install
yarn build

node_modulesを消してから入れ直すのが大事です。手元に残っているだけのパッケージが動作を支えている場合、消し忘れに気づけません。

yarn.lockの差分も見ておきます。うちがpuppeteerを外したときは、

  • puppeteerの依存ツリー(chromium-bidi、devtools-protocol、extract-zipなど)だけが消えた
  • 既存パッケージのバージョン変更は無し

という差分でした。意図しないバージョン変更が混ざっていないかは必ず確認してください。ここに気づかず一緒にコミットすると、後日「なぜか動かない」の原因が特定できなくなります。

ついでに見つかる:lockファイルの併存

棚卸しの最中に、package-lock.jsonとyarn.lockが両方あることに気づきました。

これは静かに効いてくる問題です。

  • Vercelはyarn.lockを見てインストールしている
  • package-lock.jsonは誰も見ていないのに存在する
  • 中身は乖離していて、canvasすら含まれていなかった
  • ビルドログでも混在が警告されていた

つまり「lockファイルを見ても実際に何が入るのか分からない」状態でした。手元でnpmを叩いた人と、yarnを叩いた人で、別のツリーができます。

どちらか一方に決めて、もう片方は削除してください。うちはyarnに統一しました。

git rm package-lock.json

決めたあとは、依存を変えたらlockファイルを必ずコミットするのを徹底します。lockを更新しないままpushすると、本番だけ別のバージョンが入る余地が残ります。

ビルド時間の実測

参考までに、うちの規模(ページ50本以上、ビルドマシンは2コア)での実測値です。

状況所要時間
キャッシュ無し(初回・依存変更後)約12分
キャッシュ有り+依存変更あり約1分40秒
キャッシュ有り+コード変更なし約42秒

念のため書いておくと、これは依存を消したことによる短縮の数字ではありません。 キャッシュが効くかどうかの差です。

ここで言いたいのは、依存を変えるとキャッシュが無効になるということのほうです。つまり不要な依存が残っていると、それが更新されるたびに12分側を引きます。効いてくるのは「毎回のビルドが数秒速くなる」ではなく、遅いビルドを踏む頻度のほうです。

よくある質問(FAQ)

Q. depcheckのようなツールで自動化できませんか?

洗い出しの取っかかりには便利です。ただ設定ファイル経由の参照や、CLIとして使っているものを誤検出しがちなので、出力をそのまま信じて消すのは危険です。

「候補を出させて、1つずつ手で確認する」という使い方が現実的だと思います。今回のように十数個ならgrepで十分でした。

Q. devDependenciesとdependenciesの区別は直すべきですか?

気づいたなら直しておくといいです。本番ビルドでdevDependenciesを入れない構成にしたとき、初めて痛い目を見ます。

ただしNext.jsのビルドはdevDependenciesを必要とするので、Vercelでは両方インストールされます。「直さないと壊れる」類の話ではありません。優先度は低めです。

Q. 消したあとに必要だと分かったらどうしますか?

戻せばいいだけです。gitに履歴が残っているので、バージョンごと復元できます。

消すのを怖がって残し続けるほうがコストが高いというのが今回の結論でした。使っていないものが原因で本番が止まった実績があるので、なおさらです。

Q. Vercelのビルドキャッシュは消したほうがいいですか?

依存を変えたあとの検証では、「Use existing Build Cache」を外してビルドしてください。旧環境の成果物が残っていると、検証になりません。

普段のデプロイでは、もちろん有効のままで構いません。

まとめ

  • 使っていない依存でも、postinstallやネイティブビルドは動く
  • 参照はimportの形で検索する。単語検索は誤認のもと
  • 設定ファイルとscriptsからの参照も見る
  • 消したらnode_modulesごと入れ直してビルドを通してからコミット
  • yarn.lockの差分に意図しないバージョン変更が混ざっていないか確認する
  • package-lock.jsonとyarn.lockの併存は解消する

package.jsonは、放っておくと過去に試したことの墓場になります。年に一度でも棚卸しすると、こういう地雷が減ります。


この記事が何かのお役に立てれば幸いです。
最後までお読みいただきありがとうございました!

Share Me!