ワークスペース
Voltaは、npm、Yarn、pnpmのワークスペース機能をサポートしており、モノレポ環境での開発を効率化します。このガイドでは、Voltaでワークスペースを効果的に管理する方法について説明します。
ワークスペースとは
ワークスペースは、複数の関連パッケージを単一のリポジトリで管理する方法です。これにより以下の利点があります:
- 共通の依存関係の重複を削減
- パッケージ間の依存関係管理の簡素化
- 一元的なビルドとテストプロセス
- 一貫したツールバージョンの使用
ワークスペースの設定
npmワークスペース
json
// ルートのpackage.json
{
"name": "my-monorepo",
"workspaces": [
"packages/*",
"apps/*"
],
"volta": {
"node": "18.17.0",
"npm": "9.8.0"
}
}
Yarnワークスペース
json
// ルートのpackage.json
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
],
"volta": {
"node": "18.17.0",
"yarn": "1.22.19"
}
}
pnpmワークスペース
yaml
# pnpm-workspace.yaml
packages:
- 'packages/*'
- 'apps/*'
- '!**/test/**'
json
// ルートのpackage.json
{
"name": "my-monorepo",
"volta": {
"node": "18.17.0",
"pnpm": "7.33.6"
}
}
Voltaでのワークスペース管理
ツールバージョンの統一
Voltaは、ワークスペース全体で一貫したツールバージョンを保証します:
bash
# ルートディレクトリでツールを固定
volta pin node@18.17.0 npm@9.8.0
# すべてのワークスペースパッケージが同じバージョンを使用
cd packages/ui
npm --version # 9.8.0
cd ../api
npm --version # 9.8.0
個別パッケージの設定
個別のワークスペースパッケージで異なるツールが必要な場合:
json
// packages/legacy-app/package.json
{
"name": "legacy-app",
"volta": {
"node": "14.21.3",
"npm": "6.14.18"
}
}
Voltaは、そのディレクトリで作業する際に自動的に適切なバージョンに切り替えます。
実践的なワークスペース例
フロントエンドモノレポ
my-frontend-monorepo/
├── package.json (Volta設定)
├── packages/
│ ├── ui-components/
│ │ └── package.json
│ ├── shared-utils/
│ │ └── package.json
│ └── theme/
│ └── package.json
└── apps/
├── web-app/
│ └── package.json
└── mobile-app/
└── package.json
json
// ルートのpackage.json
{
"name": "frontend-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
],
"volta": {
"node": "18.17.0",
"npm": "9.8.0"
},
"scripts": {
"build": "npm run build --workspaces",
"test": "npm run test --workspaces",
"dev": "npm run dev --workspaces"
}
}
フルスタックモノレポ
fullstack-app/
├── package.json
├── frontend/
│ ├── package.json (React 18)
│ └── src/
├── backend/
│ ├── package.json (Node.js API)
│ └── src/
├── shared/
│ ├── package.json (共通ユーティリティ)
│ └── src/
└── mobile/
├── package.json (React Native)
└── src/
一般的なワークフロー
依存関係の管理
bash
# ルートレベルで全体をインストール
npm install
# 特定のワークスペースに依存関係を追加
npm install lodash --workspace=packages/shared-utils
# ワークスペース間の依存関係を追加
npm install @myorg/shared-utils --workspace=apps/web-app
スクリプトの実行
bash
# すべてのワークスペースでスクリプトを実行
npm run build --workspaces
# 特定のワークスペースでスクリプトを実行
npm run test --workspace=packages/ui-components
# 並列実行(高速化)
npm run build --workspaces --parallel
選択的実行
bash
# 特定の条件でワークスペースを選択
npm run test --workspaces --if-present
# 依存関係がある場合のみ実行
npm run build --workspaces --include-dependencies
Yarn固有の機能
bash
# すべてのワークスペースで実行
yarn workspaces run build
# 特定のワークスペースで実行
yarn workspace web-app run dev
# ワークスペース情報を表示
yarn workspaces info
pnpm固有の機能
bash
# すべてのワークスペースで実行
pnpm run build --recursive
# フィルターで特定のワークスペースを選択
pnpm run test --filter "packages/*"
# 特定のワークスペースでコマンドを実行
pnpm --filter web-app run dev
CI/CDでのワークスペース
GitHub Actions
yaml
name: Monorepo CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
workspace: [packages/ui, packages/utils, apps/web]
steps:
- uses: actions/checkout@v3
- name: Install Volta
run: |
curl https://get.volta.sh | bash
echo "$HOME/.volta/bin" >> $GITHUB_PATH
- name: Install dependencies
run: npm ci
- name: Test workspace
run: npm run test --workspace=${{ matrix.workspace }}
変更検出の最適化
yaml
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v35
with:
files: |
packages/**
apps/**
- name: Test changed workspaces
if: steps.changed-files.outputs.any_changed == 'true'
run: |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
workspace=$(echo $file | cut -d'/' -f1-2)
npm run test --workspace=$workspace
done
ベストプラクティス
1. 一貫したツールバージョン
json
// ルートで統一されたツールバージョンを定義
{
"volta": {
"node": "18.17.0",
"npm": "9.8.0"
}
}
2. 依存関係の管理戦略
json
// ルートpackage.jsonでdevDependenciesを管理
{
"devDependencies": {
"typescript": "^5.0.0",
"eslint": "^8.0.0",
"prettier": "^3.0.0"
}
}
3. 効率的なスクリプト設定
json
{
"scripts": {
"build": "npm run build --workspaces --if-present",
"test": "npm run test --workspaces --if-present",
"lint": "eslint packages/**/*.ts apps/**/*.ts",
"clean": "npm run clean --workspaces --if-present"
}
}
トラブルシューティング
依存関係の競合
bash
# 依存関係ツリーを確認
npm ls --all
# 重複した依存関係を確認
npm ls --depth=0
# ロックファイルを再生成
rm package-lock.json
npm install
ワークスペースの認識問題
bash
# ワークスペースの設定を確認
npm query ":attr(workspaces)"
# キャッシュをクリア
npm cache clean --force
# node_modulesを再インストール
rm -rf node_modules package-lock.json
npm install
パフォーマンスの最適化
bash
# .npmrcで設定
echo "prefer-workspace-packages=true" >> .npmrc
echo "save-workspace-protocol=false" >> .npmrc
# パッケージマネージャー固有の最適化
# pnpmの場合
echo "shared-workspace-lockfile=true" >> .npmrc