build-engineer について
モノレポツール、バンドラー、インクリメンタルビルドを扱うビルドエンジニアリングスキルです。ツール選定、CI の最適化、依存関係の分析、一般的なビルド問題の調査を支援します。
主な機能
- 01モノレポツールとバンドラーの比較
- 02リモートキャッシュと並列ビルドの案内
- 03Nx の影響範囲タスクのワークフロー
- 04Bazel のビルド概念の解説
- 05依存関係と CI の問題点の特定
活用シーン
- 01モノレポ構築に使うツールの選定
- 02遅い CI パイプラインの処理量削減
- 03Webpack から Vite または Rspack への移行
- 04循環依存や未宣言依存の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ 404kidwiz/ claude-supercode-skills --skill build-engineerインストール後、Claude Code で/build-engineerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/best_practices.mdbundler_guide.mdframework_selection.mdoptimization_strategies.mdtroubleshooting.mdscripts/code_splitting.pyconfig_vite.pyconfig_webpack.pydev_server.pyoptimize_cache.pyoptimize_production.py詳細
ビルドエンジニア
目的
モノレポツール(Turborepo、Nx、Bazel)、バンドラーの最適化(Webpack/Vite/Rspack)、インクリメンタルビルドを専門とする、ビルドシステムと CI/CD の最適化に関する専門知識を提供します。キャッシュ、並列化、ビルドパフォーマンスを通じて、開発の速度を最適化することに重点を置いています。
使用する場面
- モノレポのセットアップ(pnpm workspaces + Turborepo/Nx)
- 遅い CI ビルドの最適化(リモートキャッシュ、シャーディング)
- パフォーマンス向上のため、Webpack から Vite/Rspack に移行する
- 高度な Bazel ビルドルール(Starlark)の設定
- 複雑な依存関係グラフや循環依存関係のデバッグ
- 「影響範囲に応じた」ビルドの実装(変更されたものだけをテスト)
2. 選択のためのフレームワーク
モノレポツールの選択
| ツール | 最適な用途 | メリット | デメリット |
|---|---|---|---|
| Turborepo | JS/TS エコシステム | 設定不要、シンプル、Vercel ネイティブです。 | 主に JS のみで、Bazel ほど細かく設定できません。 |
| Nx | エンタープライズ向け JS/TS | 強力なプラグイン、コード生成、グラフの可視化に対応しています。 | 設定が重く、独自の方針が強めです。 |
| Bazel | 複数言語(Go/Java/JS) | 隔離されたビルドに対応し、無限にスケールします(Google 方式)。 | 習得に非常に時間がかかり、セットアップも複雑です。 |
| Pnpm Workspaces | シンプルなプロジェクト | Node.js 標準で、インストールが高速です。 | タスクのオーケストレーション機能はありません(Turbo/Nx が必要です)。 |
バンドラーの選択
What is the priority?
│
├─ **Development Speed (HMR)**
│ ├─ Web App? → **Vite** (ESModules based, instant start)
│ └─ Legacy App? → **Rspack** (Webpack compatible, Rust speed)
│
├─ **Production Optimization**
│ ├─ Max Compression? → **Webpack** (Mature ecosystem of plugins)
│ └─ Speed? → **Rspack / Esbuild**
│
└─ **Library Authoring**
└─ Dual Emit (CJS/ESM)? → **Rollup** (Tree-shaking standard)
危険信号 → devops-engineer にエスカレーションしてください:
- CI パイプラインに 20 分以上かかる
node_modulesのサイズが 1GB を超えている(ファントム依存関係)- 「自分のマシンでは動く」のに CI では失敗する(環境の差異)
- ビルド成果物内にシークレットキーが見つかる(ソースマップ)
4. 主なワークフロー
ワークフロー 1:Turborepo のセットアップ(リモートキャッシュ)
目標: キャッシュ成果物を再利用して、CI の実行時間を 80% 短縮します。
手順:
-
設定(
turbo.json){ "$schema": "https://turbo.build/schema.json", "pipeline": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**"] }, "test": { "dependsOn": ["build"], "inputs": ["src/**/*.tsx", "test/**/*.ts"] }, "lint": {} } } -
リモートキャッシュ
- Vercel Remote Cache にリンクします:
npx turbo link。 - CI(GitHub Actions)で:
env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- Vercel Remote Cache にリンクします:
-
実行
turbo run build test lint- 初回実行:5 分。2 回目の実行:100ms(FULL TURBO)。
ワークフロー 3:Nx の影響範囲に応じたコマンド
目標: モノレポ内で変更されたプロジェクトのテストだけを実行します。
手順:
-
グラフを分析する
nx graph(依存関係を可視化します:App A は Lib B に依存しています)。
-
CI パイプライン
# PR の影響を受けるプロジェクトだけをテスト npx nx affected -t test --base=origin/main --head=HEAD # 影響を受けるものだけを lint npx nx affected -t lint --base=origin/main
ワークフロー 5:JS 開発者向けの Bazel の概念
目標: BUILD ファイルと package.json の違いを理解します。
対応関係:
| NPM の概念 | Bazel の概念 |
|---|---|
package.json | WORKSPACE / MODULE.bazel |
script: build | js_library(name = "build") |
dependencies | deps = ["//libs/utils"] |
node_modules | npm_link_all_packages |
コード例(BUILD.bazel):
load("@aspect_rules_js//js:defs.bzl", "js_library")
js_library(
name = "pkg",
srcs = ["index.js"],
deps = [
"//:node_modules/lodash",
"//libs/utils"
],
)
5. アンチパターンと注意点
❌ アンチパターン 1:ファントム依存関係
どのような状態か:
import foo from 'foo'はローカルでは動作するものの、CI では失敗します。
失敗する理由:
- パッケージマネージャーによって 'foo' がホイストされているものの、
package.jsonに記載されていません。
適切な方法:
- pnpm(Strict モード)を使用します。シンボリックリンクを介した、宣言されていない依存関係へのアクセスを防ぎます。
❌ アンチパターン 2:循環依存
どのような状態か:
- Lib A が Lib B をインポートし、Lib B が Lib A をインポートします。
- 「Maximum call stack exceeded」または「Undefined symbol」が表示され、ビルドに失敗します。
失敗する理由:
- アーキテクチャ上のロジックエラーです。
正しいアプローチ:
- 共有コードを切り出す: 共通のロジックを Lib C に移します。
- A → C、B → C。
madgeツールを使用して循環依存を検出します:npx madge --circular .
❌ アンチパターン 3:node_modules のコミット
どのような状態か:
- Git リポジトリのサイズが 2GB になります。
失敗する理由:
- クローンに時間がかかります。プラットフォーム固有のバイナリが問題を引き起こします。
正しいアプローチ:
.gitignoreにnode_modules/、dist/、.turbo/、.next/を含める必要があります。
7. 品質チェックリスト
パフォーマンス:
- キャッシュ: リモートキャッシュが有効化され、検証済みです(ヒット率 > 80%)。
- 並列処理: 可能な場合、タスクが並列で実行されます(トポロジーを考慮)。
- サイズ: 本番用アーティファクトが最小化され、ツリーシェイキングされています。
信頼性:
- ロックファイル:
pnpm-lock.yaml/package-lock.jsonに一貫性があります。 - CI: クリーンなランナー(キャッシュなし)でビルドが成功します。
- 決定性: 同じ入力 = 同じハッシュ。
保守性:
- スクリプト:
package.jsonのスクリプトが標準化されています(dev、build、test、lint)。 - グラフ: 依存関係グラフに循環がありません(DAG)。
- スキャフォールディング: 新しいライブラリ/アプリ用のジェネレーターが設定されています。
例
例 1:エンタープライズモノレポへの移行
シナリオ: React アプリケーション 4 つと共有ライブラリ 15 個を持つ、開発者 500 人の企業が、コード共有と CI 効率を改善するため、個別のリポジトリからモノレポへの移行を検討しています。
移行アプローチ:
- ツールの選定: エンタープライズ向け機能とグラフの可視化を理由に Nx を選択しました
- 依存関係のマッピング: madge を使用して、プロジェクト間の現在の依存関係を可視化しました
- モジュール境界: 明確なレイヤー(ui、utils、data-access、features)を定義しました
- ビルドの最適化: Nx Cloud でリモートキャッシュを設定しました
移行結果:
- CI のビルド時間が 45 分から 8 分に短縮されました(82% 改善)
- 共有ライブラリにより、コードの重複が 60% 削減されました
- 変更されたプロジェクトのみを対象にビルドとテストを実行します(多くの場合 1 分未満)
- Nx のプロジェクト推論によって、明確なアーキテクチャ境界が適用されます
例 2:Webpack から Rspack への移行
シナリオ: 大規模な e コマースプラットフォームで、複雑な Webpack 設定が原因で本番ビルドに時間がかかっており(12 分)、開発者体験の改善を目指しています。
移行戦略:
- 段階的な移行: 開発ビルドから開始し、一時的に本番環境では Webpack を使い続けました
- 設定の変換: Webpack ローダーを Rspack の同等機能に対応付けました
- プラグインの互換性: Webpack 互換プラグインには rspack-plugins を使用しました
- 検証: 並列ビルドを実行して、出力が同等であることを検証しました
パフォーマンス比較:
| 指標 | Webpack | Rspack | 改善率 |
|---|---|---|---|
| 開発サーバーの起動 | 45s | 2s | 96% |
| HMR の更新 | 8s | 0.5s | 94% |
| 本番ビルド | 12m | 2m | 83% |
| バンドルサイズ | 2.4MB | 2.3MB | 4% |
例 3:シャーディングを用いた分散 CI パイプライン
シナリオ: E2E テストを 5,000 件持つゲーム会社が、迅速なフィードバックを得るため、CI 時間を 90 分から 15 分未満に短縮する必要があります。
パイプライン設計:
- テスト分析: テストを所要時間と並列化の可能性に基づいて分類しました
- シャード戦略: テストを 20 個のシャードに分割し、それぞれ約 250 件のテストを実行します
- スマートスケジューリング: Nx affected を使用して、変更された機能のテストのみを実行しました
- リソースの最適化: 並列実行用に自動スケーリングランナーを設定しました
CI パイプライン設定:
# GitHub Actions with Playwright sharding
- name: Run E2E Tests
run: |
npx playwright test --shard=${{ matrix.shard }}/${{ matrix.total }} \
--config=playwright.config.ts
strategy:
matrix:
shard: [1, 2, ..., 20]
max-parallel: 10
結果:
- E2E テスト時間:90m → 12m(87% 改善)
- 開発者へのフィードバックが 15 分未満で得られます
- 並列処理の改善により、クラウド CI コストを 30% 削減しました
ベストプラクティス
モノレポのアーキテクチャ
- 明確な境界を定義する:最初からプロジェクトの境界を定め、適用します
- 厳格な依存関係ルールを採用する:循環依存を防ぎ、依存の方向性を徹底します
- プロジェクト作成を自動化する:ジェネレーターを使い、新しいプロジェクトを一貫した方法でセットアップします
- パッケージをまとめてバージョン管理する:Changesets または Lerna を使い、リリースを連携させます
- 依存関係を文書化する:変更に関するアーキテクチャ決定記録を管理します
ビルドパフォーマンス
- 最適化の前にプロファイリングする:speed-measure-webpack-plugin などのツールを使ってボトルネックを特定します
- インクリメンタルビルド:必要な箇所だけを再ビルドするよう、ビルドツールを設定します
- 並列実行:利用可能な CPU コアを使ってタスクを並列実行します
- キャッシュ戦略:あらゆるレイヤーで積極的にキャッシュを導入します
- 依存関係の最適化:未使用の依存関係を定期的に削除します(bundlephobia)
CI/CD の強化
- 迅速に失敗させる:テストを高速なものから実行するよう順序を設定し、失敗を早く検出します
- シャーディング戦略:複数のランナーにテストを適切に分散します
- すべてをキャッシュする:依存関係、ビルド成果物、テスト結果をキャッシュします
- 条件付き実行:変更の影響を受けるジョブのみを実行します
- コードとしてのパイプライン:CI 設定をコードとともにバージョン管理します
ツールの選定
- エコシステムに合ったツールを選ぶ:スタックに合わないツールを無理に使わないでください
- 移行コストを評価する:パフォーマンス向上だけでなく、総コストを考慮します
- コミュニティの健全性:積極的にメンテナンスされ、コミュニティのサポートがあるツールを選びます
- プラグインのエコシステム:必要な連携機能が利用できることを確認します
- チームの習熟度:学習曲線とチームへの定着を考慮します
セキュリティとコンプライアンス
- シークレットスキャン:シークレットをコミットせず、自動スキャンを利用します
- 依存関係の監査:自動修正機能を備えた脆弱性スキャンを定期的に実施します
- アクセス制御:CI の認証情報に必要最小限の権限のみを付与します
- ビルドの再現性:ソースからビルドを再現できるようにします
- 監査ログ:すべてのビルドおよびデプロイの活動に関するログを管理します