Turboを活用したモノレポの依存関係管理

Turboの特徴と利点

前回の記事では型定義パッケージの作成方法について解説しました。今回は、モノレポの効率的な管理を実現する「Turbo」について説明します。

Turboは、JavaScriptやTypeScriptのモノレポを効率的に管理できるビルドシステムです。主な特徴は以下の通りです:

  • 高速なタスク実行
  • インテリジェントなキャッシュ戦略
  • 効率的な並列実行

turbo.jsonの基本的な設定例:

{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": [".env*"],
  "globalEnv": ["NODE_ENV", "CI", "VERCEL"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [
        ".next/**",
        "!.next/cache/**",
        "dist/**",
        "storybook-static/**"
      ]
    },
    "test": {
      "dependsOn": ["^build"],
      "outputs": ["coverage/**"]
    },
    "lint": {
      "outputs": [".eslintcache"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

ワークスペースの管理も簡単!

package.jsonでワークスペースの設定をします:

{
  "name": "sample-monorepo",
  "private": true,
  "scripts": {
    "build": "turbo build",
    "dev": "turbo dev",
    "lint": "turbo lint",
    "test": "turbo test",
    "clean": "turbo clean && rm -rf node_modules",
    "typecheck": "turbo typecheck"
  }
}

依存関係をスッキリ管理!

pnpmの設定を極める

.npmrcファイルで依存関係の管理方法を設定:

# 厳密な依存関係チェックは無効に
strict-peer-dependencies=false

# ピア依存関係の自動インストール
auto-install-peers=true

# 重複を排除
dedupe-peer-dependencies=true

# node_modulesの構造を最適化
shamefully-hoist=true

# ワークスペースパッケージを優先
prefer-workspace-packages=true

# 依存関係の管理方法
node-linker=hoisted

バージョン管理のコツ!

package.jsonでバージョンを一元管理:

{
  "pnpm": {
    "overrides": {
      "react": "^18.2.0",
      "react-dom": "^18.2.0",
      "@types/react": "^18.2.55",
      "@types/react-dom": "^18.2.19"
    },
    "peerDependencyRules": {
      "allowedVersions": {
        "react": "18",
        "react-dom": "18"
      }
    }
  }
}

共通設定を使いまわそう!

ESLintの設定を共有

module.exports = {
  extends: ['@sample/eslint-config/nextjs'],
  rules: {
    '@typescript-eslint/no-unused-vars': [
      'error',
      {
        argsIgnorePattern: '^*',
        varsIgnorePattern: '^_',
      },
    ],
    '@typescript-eslint/no-explicit-any': 'warn',
  },
};

TypeScriptの設定も共有しよう

base.jsonの設定例:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Default",
  "compilerOptions": {
    "composite": false,
    "declaration": true,
    "declarationMap": true,
    "esModuleInterop": true,
    "isolatedModules": true,
    "moduleResolution": "node",
    "strict": true
  }
}

Tailwindの設定も共有できる!

module.exports = {
  darkMode: ['class'],
  content: ['./src/**/*.{ts,tsx}'],
  theme: {
    extend: {
      colors: {
        border: 'hsl(var(--border))',
        input: 'hsl(var(--input))',
        ring: 'hsl(var(--ring))',
        background: 'hsl(var(--background))',
        foreground: 'hsl(var(--foreground))',
      },
    },
  },
  plugins: [require('tailwindcss-animate')],
};

ビルドを爆速にする裏技!

キャッシュを使いこなす

Turboのキャッシュ機能がすごい:

  • .turboディレクトリに自動でキャッシュ
  • チーム全員でキャッシュを共有できる
  • 差分ビルドで爆速に!

Turboは賢く並列実行してくれます:

1. 依存関係のないタスクは同時に実行⚡️

️2. 依存関係があるタスクは順番に実行🧹

3. CPUパワーを最大限活用👥

CI/CDも自動化!

GitHub Actionsの設定例:

name: CI

on:
push:
branches: ['main']
pull_request:
types: [opened, synchronize]

jobs:
build:
runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2
with:
version: 9 - name: Build
run: pnpm build - name: Test
run: pnpm test

## まとめ

Turboを使うことで:

  • ビルドが爆速に!
  • 設定がスッキリ!
  • チーム開発が捗る!

便利な小技集

  • turbo pruneでデプロイ用の依存関係を最適化!
  • --forceフラグでキャッシュを無視できる
  • --parallelフラグで並列実行を制御できる