Angular CLI高度活用とワークスペース管理
Angular CLIはプロジェクトの作成だけでなく、コード生成、ライブラリ管理、ビルド最適化まで包括的な開発体験を提供します。大規模開発においてCLIの活用は生産性とコードの一貫性を大幅に向上させます。
1. ng generate による統一的なコード生成
ng generate(短縮形: ng g)は、コンポーネントやサービスなどのファイルをAngularのベストプラクティスに沿った形で自動生成するコマンドです。チーム全員が同じコマンドを使うことで、ファイル命名・ディレクトリ構造・テストファイルの有無を統一できます。
主要な generate コマンド
# スタンドアロンコンポーネント(Angular 17+ デフォルト)
ng g component features/user-profile
# NgModule 型コンポーネント(レガシー)
ng g component features/user-profile --no-standalone
# インラインスタイル・インラインテンプレートでコンパクトに
ng g component shared/badge --inline-style --inline-template
# テストファイルをスキップ
ng g component shared/spinner --skip-tests
# サービス
ng g service core/auth
# ディレクティブ
ng g directive shared/directives/highlight
# パイプ
ng g pipe shared/pipes/truncate
# ガード(ルートの保護)
ng g guard core/guards/auth --implements CanActivate
# HTTP インターセプター
ng g interceptor core/interceptors/auth-token
# リゾルバー(ルートデータの事前取得)
ng g resolver features/user/user-detail
主要オプション一覧
| オプション | 説明 | デフォルト |
|---|---|---|
--standalone | スタンドアロンコンポーネントとして生成 | true(v17+) |
--skip-tests | .spec.ts ファイルを生成しない | false |
--inline-style | スタイルを .ts 内に記述 | false |
--inline-template | テンプレートを .ts 内に記述 | false |
--flat | サブディレクトリを作らない | false |
--dry-run | 実際に生成せず確認のみ | false |
--prefix | セレクタのプレフィックスを指定 | app |
Reactには公式のコード生成ツールがなく、コンポーネントは手動でファイルを作成します。チームごとに plop.js や hygen などを導入することはありますが、Angular CLIのような標準化されたツールはありません。
# React(手動 or サードパーティ)
touch src/components/UserProfile/index.tsx
touch src/components/UserProfile/UserProfile.test.tsx
# Angular(標準)
ng g component features/user-profile
# → user-profile.component.ts, .html, .css, .spec.ts が自動生成
生成されるファイル例
ng g component features/user-profile --standalone
# CREATE src/app/features/user-profile/user-profile.component.ts
# CREATE src/app/features/user-profile/user-profile.component.html
# CREATE src/app/features/user-profile/user-profile.component.css
# CREATE src/app/features/user-profile/user-profile.component.spec.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-user-profile',
standalone: true,
imports: [CommonModule],
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.css']
})
export class UserProfileComponent {}
2. Angular ライブラリの作成と管理
Angular CLIはモノレポ内で共有ライブラリを作成・管理する機能を内包しています。UIコンポーネントライブラリ、ユーティリティ関数、共通サービスなどをライブラリとして切り出すことで、複数アプリ間での再利用が容易になります。
ライブラリの作成
ng generate library mylib
# ワークスペース構造:
# projects/
# mylib/
# src/
# lib/
# mylib.component.ts
# mylib.module.ts
# mylib.service.ts
# public-api.ts ← エクスポートポイント
# ng-package.json ← ng-packagr 設定
# tsconfig.lib.json
# tsconfig.spec.json
public-api.ts によるエクスポート管理
// ライブラリの公開APIをここで一元管理
export * from './lib/mylib.component';
export * from './lib/mylib.service';
export * from './lib/button/button.component';
export * from './lib/models/user.model';
public-api.ts はライブラリの「玄関口」です。ここにエクスポートされていないものは、ライブラリ外から利用できません。内部実装の隠蔽(カプセル化)に活用できます。
ライブラリのビルド
ng build mylib
# dist/mylib/ に成果物が出力される:
# dist/mylib/
# esm2022/
# fesm2022/
# package.json
# index.d.ts
ワークスペース内でのライブラリ利用
{
"compilerOptions": {
"paths": {
"mylib": ["dist/mylib"]
}
}
}
import { MylibComponent } from 'mylib';
@Component({
standalone: true,
imports: [MylibComponent],
template: `<mylib-root />`
})
export class AppComponent {}
ライブラリの開発時ウォッチモード
# ライブラリを監視ビルドしながらアプリを起動
ng build mylib --watch &
ng serve
| 特徴 | Angular Library | React + Turborepo |
|---|---|---|
| ライブラリ作成 | ng g library mylib | turbo gen workspace --name mylib |
| ビルドツール | ng-packagr(Angular最適化) | tsc / tsup / vite |
| パスエイリアス | tsconfig で自動設定 | tsconfig.json 手動設定 |
| バンドル形式 | ESM + CJS + UMD | 設定次第 |
| 型定義 | 自動生成 | 自動生成 |
Angular CLIはAngularに特化した最適化(partial Ivy compilation)が自動適用されます。
3. Schematics(コード生成の自動化)
SchematicsはAngular CLIのコード生成・変換エンジンです。ASTベースでソースコードを解析・変換する仕組みで、ng generate や ng add、ng update の裏側で動いています。
Schematics の仕組み
サードパーティ Schematic の実行
# Angular Material をワークスペースに追加
# → package.json 更新、module への import 追加、テーマ設定まで自動実行
ng add @angular/material
# ESLint を追加
ng add @angular-eslint/schematics
# PWA サポートを追加
ng add @angular/pwa
カスタム Schematic の概要
npm install -g @angular-devkit/schematics-cli
schematics blank --name=my-schematics
cd my-schematics
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
export function myComponent(options: { name: string }): Rule {
return (tree: Tree, context: SchematicContext) => {
const content = `
import { Component } from '@angular/core';
@Component({
selector: 'app-${options.name}',
standalone: true,
template: '<div>${options.name} works!</div>'
})
export class ${capitalize(options.name)}Component {}
`.trim();
tree.create(`src/app/${options.name}/${options.name}.component.ts`, content);
return tree;
};
}
function capitalize(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
マイグレーション Schematic(ng update で使用)
ng update はパッケージのバージョンアップ時にマイグレーション Schematic を自動実行します。
ng update @angular/core @angular/cli
# 出力例:
# Using package manager: npm
# Collecting installed dependencies...
# Fetching dependency metadata from registry...
# Package '@angular/core' is already up-to-date.
# Updating package.json with dependency @angular/core @ "17.0.0"...
# Running migrations of package '@angular/core'...
# ✓ Migration: Update standalone API usage.
# ✓ Migration: Remove deprecated lifecycle hooks.
# UPDATE src/app/app.module.ts (345 bytes)
# UPDATE src/app/main.ts (214 bytes)
| ツール | 用途 | 仕組み |
|---|---|---|
| Angular Schematics | コード生成・マイグレーション | AST変換、公式標準 |
| Plop.js(React) | テンプレートからのコード生成 | Handlebarsテンプレート |
| Hygen(React) | ファイル生成 | EJSテンプレート |
| codemod(React) | マイグレーション | jscodeshift AST変換 |
Angular の ng update は公式マイグレーションが標準装備されているため、メジャーバージョンアップも安全に自動化できます。React のメジャーアップグレードは公式の自動化ツールが少なく、手動対応が多くなりがちです。
4. Nx によるモノレポ管理
Nxは大規模なAngularモノレポ管理のためのビルドシステムです。複数のアプリとライブラリを1つのリポジトリで管理し、依存関係グラフに基づいた差分ビルド・テストで開発速度を大幅に向上させます。
Nx ワークスペースの作成
# 新規作成
npx create-nx-workspace@latest my-org --preset=angular-monorepo
# 既存 Angular ワークスペースへの追加
ng add @nx/angular
モノレポのディレクトリ構造
my-org/
├── apps/
│ ├── app-a/ ← Angular アプリ A
│ └── app-b/ ← Angular アプリ B
├── libs/
│ ├── shared/ ← 共通ライブラリ
│ │ ├── ui/ ← 共通 UI コンポーネント
│ │ └── util/ ← 共通ユーティリティ
│ └── feature/ ← 機能ライブラリ
├── nx.json ← Nx 設定
└── package.json
プロジェクト依存グラフ
依存グラフを視覚化するには次のコマンドを実行します:
nx graph
# → ブラウザで依存関係グラフが表示される
affected コマンド(差分ビルド・テスト)
# main ブランチとの差分があるプロジェクトのみビルド
nx affected:build --base=main
# 差分があるプロジェクトのみテスト
nx affected:test --base=main
# 差分があるプロジェクトのみ lint
nx affected:lint --base=main
# CI での一般的な使用例
nx affected --target=build --base=origin/main --head=HEAD
キャッシュとリモートキャッシュ
# ローカルキャッシュは ~/.nx/cache に自動保存
nx build app-a
# → 2回目以降はキャッシュから即時完了
# Nx Cloud でリモートキャッシュ(チーム間で共有)
nx connect
{
"tasksRunnerOptions": {
"default": {
"runner": "@nx/cloud",
"options": {
"cacheableOperations": ["build", "test", "lint", "e2e"],
"accessToken": "YOUR_NX_CLOUD_TOKEN"
}
}
}
}
モジュール境界ルール
{
"rules": {
"@nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{
"sourceTag": "scope:app",
"onlyDependOnLibsWithTags": ["scope:shared", "scope:feature"]
},
{
"sourceTag": "scope:feature",
"onlyDependOnLibsWithTags": ["scope:shared"]
},
{
"sourceTag": "scope:shared",
"onlyDependOnLibsWithTags": ["scope:shared"]
}
]
}
]
}
}
| 機能 | Nx(Angular) | Turborepo(Next.js) |
|---|---|---|
| 差分ビルド | nx affected:build | turbo run build --filter=[origin/main] |
| キャッシュ | ローカル + Nx Cloud | ローカル + Vercel Remote Cache |
| 依存グラフ | nx graph(GUI) | turbo run --graph |
| 境界ルール | @nx/enforce-module-boundaries | 独自 lint ルール |
| Code Generation | nx generate | turbo gen |
| フレームワーク依存 | Angular 最適化あり | フレームワーク非依存 |
Nxはエンタープライズ向けの機能(タスクオーケストレーション、CI統合、コード所有権管理)が充実しています。
5. angular.json のワークスペース設定
angular.json はAngular CLIのワークスペース全体の設定ファイルです。ビルド・サーブ・テストの詳細設定、バンドルサイズ制限、環境切り替えなどを一元管理します。
angular.json の基本構造
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"my-app": {
"projectType": "application",
"root": "",
"sourceRoot": "src",
"architect": {
"build": { ... },
"serve": { ... },
"test": { ... },
"lint": { ... }
}
}
}
}
build ターゲットの詳細設定
{
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": "dist/my-app",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets",
{ "glob": "**/*", "input": "public", "output": "/" }
],
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
}
],
"outputHashing": "all",
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
}
}
}
budgets(バンドルサイズ制限)
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
},
{
"type": "anyScript",
"maximumWarning": "150kB",
"maximumError": "300kB"
}
]
type | 対象 |
|---|---|
initial | 初期ロードバンドル合計 |
anyScript | 個別スクリプトファイル |
anyComponentStyle | 個別コンポーネントCSS |
bundle | 特定バンドル名指定 |
fileReplacements(環境別ファイル切り替え)
export const environment = {
production: false,
apiUrl: 'http://localhost:3000/api',
featureFlags: { newDashboard: true }
};
export const environment = {
production: true,
apiUrl: 'https://api.example.com',
featureFlags: { newDashboard: false }
};
ng build --configuration=production
ng serve --configuration=development
Next.jsでは .env.local, .env.production 等の環境変数ファイルで切り替えます。Angularの fileReplacements は型安全な環境設定の切り替えが可能で、TypeScript の型チェックが効くのが利点です。
6. カスタムビルダー(Builders)
Builders(旧: Architects)はAngular CLIのコマンド(ng build, ng serve, ng test など)の実装を差し替える仕組みです。@angular-devkit/architect パッケージが基盤となっています。
esbuild ビルダーへの切り替え(Angular 17+)
Angular 17以降、デフォルトビルダーが application(esbuild ベース)に変更されました。既存プロジェクトは browser(Webpack)から移行できます。
{
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"browser": "src/main.ts"
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"buildTarget": "my-app:build"
}
}
}
}
ビルド時間の比較
| ビルダー | 初回ビルド | 再ビルド(差分) | バンドルサイズ |
|---|---|---|---|
Webpack(旧 browser) | 約 30〜60秒 | 約 5〜10秒 | 標準 |
esbuild(新 application) | 約 5〜10秒 | 約 1〜3秒 | 同等〜小さい |
カスタムビルダーの参照
独自のビルドプロセスが必要な場合、ローカルビルダーを作成して参照できます。
{
"architect": {
"build": {
"builder": "./tools/builders/custom-builder:build"
}
}
}
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';
interface Options extends JsonObject {
outputPath: string;
}
async function customBuild(options: Options, context: BuilderContext): Promise<BuilderOutput> {
context.logger.info(`Building to ${options.outputPath}...`);
// カスタムビルドロジック
return { success: true };
}
export default createBuilder(customBuild);
サードパーティ Builders の例
# Jest をテストランナーとして使用
ng add @briebug/jest-schematic
# Storybook の統合
ng add @storybook/angular
# Tailwind CSS の追加
ng add ngx-tailwind
Next.js / Viteベースのプロジェクトと比べ、Angular 17+ のesbuildビルダーは同等以上のビルド速度を実現しています。HMR(Hot Module Replacement)も大幅に改善されました。
7. CLI による品質管理の自動化
Angular CLIには、コード品質・依存関係管理・デプロイを自動化するコマンドが揃っています。
ng lint(ESLint 統合)
# ESLint を追加
ng add @angular-eslint/schematics
# lint 実行
ng lint
# 自動修正
ng lint --fix
{
"root": true,
"ignorePatterns": ["**/*"],
"plugins": ["@nx"],
"overrides": [
{
"files": ["*.ts"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@angular-eslint/recommended"
],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{ "type": "attribute", "prefix": "app", "style": "camelCase" }
],
"@angular-eslint/component-selector": [
"error",
{ "type": "element", "prefix": "app", "style": "kebab-case" }
]
}
}
]
}
ng update(依存関係の自動更新)
# 更新可能なパッケージを確認
ng update
# Angular コアパッケージを更新(マイグレーション自動実行)
ng update @angular/core @angular/cli
# 特定バージョンへの更新
ng update @angular/core@17
# 出力例:
# ✓ Migration: Migrate to standalone APIs.
# ✓ Migration: Replace deprecated providedIn 'any'.
# UPDATE src/app/app.module.ts
# UPDATE src/app/main.ts
ReactやNext.jsのメジャーアップグレードは手動対応が多く、破壊的変更を自分で調べてコードを修正する必要があります。Angular の ng update は公式マイグレーション Schematic が自動実行されるため、大規模リファクタリングが省力化されます。
ng deploy(デプロイの自動化)
# Firebase Hosting 用デプロイビルダーを追加
ng add @angular/fire
# デプロイ実行
ng deploy
# プロジェクトを指定してデプロイ
ng deploy --project=my-app
ng add @azure/ng-deploy
ng deploy
GitHub Actions CI/CD パイプライン
name: Angular CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: ng lint
- name: Test
run: ng test --watch=false --browsers=ChromeHeadless --code-coverage
- name: Build (production)
run: ng build --configuration production
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
directory: ./coverage
deploy:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build for production
run: ng build --configuration production
- name: Deploy to Firebase
uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
channelId: live
品質管理コマンドまとめ
| コマンド | 目的 | React/Next.js 相当 |
|---|---|---|
ng lint | ESLint 実行 | eslint . |
ng test | Karma/Jest テスト | jest |
ng e2e | E2E テスト(Cypress/Playwright) | cypress run |
ng update | 依存関係更新 + マイグレーション | npm-check-updates + 手動 |
ng deploy | ホスティングへのデプロイ | vercel / firebase deploy |
ng build --stats-json | バンドル分析用 JSON 生成 | ANALYZE=true next build |
ng build --stats-json
npx webpack-bundle-analyzer dist/my-app/stats.json
Angular CLIはコード生成から品質管理・デプロイまでを一貫して担う強力なツールチェーンです。React/Next.js では複数のサードパーティツール(ESLint, Prettier, Plop, Turborepo, Vercel CLI 等)を組み合わせる必要がある作業を、Angular では ng コマンド一本で統一して管理できます。大規模チーム開発においてこの統一性は、ルールの徹底・オンボーディングの簡素化・CI/CD構築のコスト削減に大きく貢献します。