BunでCIを極限まで加速する:GitHub Actionsにおける「依存解決」の革命的アプローチ
テックリードとして現場を見渡すと、多くのチームが「CIの待ち時間」という名の見えないコストを垂れ流しています。特に巨大なモノレポや依存関係の深いプロジェクトにおいて、`npm install` や `yarn install` がCI実行時間の6割を占める光景は、もはや古典的な悪夢です。
本稿では、次世代JSランタイム「Bun」をGitHub Actionsに導入し、単に「速い」という評価を超えて、「ローカルとCIの実行速度を完全に同期させる」ためのアーキテクチャを伝授します。
—
1. なぜ「npm」ではなく「Bun」なのか:技術的解像度を高める
Bunは単なる実行環境ではありません。彼らが実装した `bun install` は、システムコールレベルで最適化されたグローバルモジュールキャッシュと、並列ダウンロードを極限まで突き詰めたバイナリ実行ファイルです。
- ロックファイル(bun.lockb)のバイナリ化: `package-lock.json` が肥大化してパースコストが増大するのに対し、`bun.lockb` はバイナリフォーマットです。これにより、CI環境での依存解決のオーバーヘッドがほぼゼロになります。
- グローバルキャッシュの共有: `~/.bun/install/cache` をGitHub Actionsのキャッシュディレクトリとしてマウントすることで、一度取得した依存関係を二度とDLしない「物理的な高速化」を実現します。
2. GitHub Actionsにおける「神」ワークフロー実装
以下のワークフローは、単にBunを入れるだけでなく、キャッシュのキー戦略を最適化し、CIのコールドスタートを最小化する構成です。
name: CI with Bun
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Bunのセットアップ。ここで最新版を固定することで冪等性を担保
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
# キャッシュ戦略: OSとロックファイルハッシュをキーにする
# これにより、依存関係が変更されたときのみキャッシュを再作成
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles(‘/bun.lockb’) }}
restore-keys: |
${{ runner.os }}-bun-
# installコマンドの実行。–frozen-lockfileは必須
# CI環境ではロックファイルが改竄されていないことを保証する
- name: Install dependencies
run: bun install –frozen-lockfile
# ビルド実行。BunはTypeScriptをネイティブサポートしているため
# tscを介さず直接実行可能な場合が多く、ここでもオーバーヘッドを削減
- name: Build
run: bun run build
—
3. プロの現場で差がつく「設定の標準化」とテクニック
A. チーム開発における「bun.lockb」の運用ルール
`bun.lockb` はバイナリであるため、Gitの差分を確認できません。これを補うために、CIのパイプライン内で以下を強制してください。
- ルール: `bun install` 実行後に `bun pm hash` を確認する。
- 運用: チームメンバー全員が同じバージョンのBunを使うよう、`package.json` に `engines` フィールドを記述し、プロジェクトルートに `.bun-version` ファイルを置く運用を徹底してください。
B. 開発効率を跳ね上げる「絶対入れるべき」プラグインと設定
VS CodeでBunを本格運用するなら、以下の設定を `.vscode/settings.json` に投入してください。Bunの型定義が自動補完され、開発体験が激変します。
{
“typescript.tsdk”: “node_modules/typescript/lib”,
// Bunの型定義を有効化し、ランタイムAPIの補完を効かせる
“typescript.preferences.importModuleSpecifierPreference”: “non-relative”,
“bun.runtimePath”: “/usr/local/bin/bun”
}
C. 知る人ぞ知るキーボードショートカット(VS Code + Bun)
- `Cmd + Shift + P` -> `Bun: Install` (Bun Extension導入時): 手動でコマンドを打たず、エディタ上から依存を即座に最新化できます。
- ライブリロードの極意: `bun –hot` を活用してください。これを使うと、コード変更時にプロセスを再起動せず、メモリ状態を維持したままモジュールのみをホットリロードできます。開発中のストレスが90%削減されます。
—
4. アーキテクトからの提言:CI/CDの「時間」は「知的リソース」である
CIが10分かかるチームと、2分で終わるチーム。この8分の差は、単なる待ち時間ではありません。「コンテキストスイッチ」のコストです。
CIを待っている間、エンジニアは他の作業に手を出し、集中力を削がれます。Bunを導入してCIを高速化することは、チームの「フロー状態」を保護するための投資です。
明日からやるべきこと:
1. 既存の `package-lock.json` を捨てず、`bun install` を実行して `bun.lockb` を生成する。
2. CIの実行ログを比較し、インストール時間が何秒短縮されたかを可視化する。
3. 浮いた時間で、技術負債の解消やリファクタリングに手を付ける。
ツールは導入して終わりではありません。そのツールが内部でどう動き、どうキャッシュを管理しているかを理解した時、初めて「伝説的な開発環境」があなたのチームの手元に完成するのです。