Nx Complete Guide | Smart Monorepo Build System
이 글의 핵심
Nx is a smart, fast, and extensible build system for monorepos. It provides computation caching, task orchestration, and code generation for TypeScript/JavaScript projects.
Introduction
Nx is a next-generation build system with first-class monorepo support and powerful integrations. Created by former Angular team members at Nrwl, it’s designed for building at scale.
Why Nx?
Traditional monorepo:
# Build everything (slow!)
npm run build
# No caching
# No dependency graph
# No task orchestration
With Nx:
# Build only what changed
nx build
# Uses computation cache
# Understands dependencies
# Runs tasks in optimal order
1. Installation
New Workspace
npx create-nx-workspace@latest my-workspace
Options:
- Integrated monorepo (recommended for new projects)
- Package-based monorepo (for existing workspaces)
- Standalone app (single project)
Add to Existing Project
npx nx@latest init
Works with existing npm/yarn/pnpm workspaces!
2. Basic Commands
# Run task
nx build my-app
# Run for all projects
nx run-many -t build
# Run affected (only changed projects)
nx affected -t build
# Show dependency graph
nx graph
# Show what's affected
nx show projects --affected
3. Workspace Structure
my-workspace/
├── apps/
│ ├── web/
│ │ ├── src/
│ │ ├── project.json
│ │ └── tsconfig.json
│ └── api/
│ ├── src/
│ └── project.json
├── libs/
│ ├── ui/
│ │ ├── src/
│ │ └── project.json
│ └── utils/
│ ├── src/
│ └── project.json
├── nx.json
├── package.json
└── tsconfig.base.json
4. Creating Projects
Generate App
# React app
nx g @nx/react:app web
# Next.js app
nx g @nx/next:app marketing
# Node.js app
nx g @nx/node:app api
Generate Library
# React library
nx g @nx/react:lib ui
# TypeScript library
nx g @nx/js:lib utils
# Nest.js library
nx g @nx/nest:lib data-access
5. Computation Caching
Nx caches task outputs:
# First run: builds and caches
nx build my-app
# Build time: 45s
# Second run: uses cache
nx build my-app
# Build time: 0.2s (from cache!)
What’s cached:
- Build outputs
- Test results
- Lint results
- Any custom task
Remote Caching
# Enable Nx Cloud
nx connect
# Now cache is shared across team and CI!
# Developer A builds
nx build my-app
# 45s, uploads to Nx Cloud
# Developer B builds same code
nx build my-app
# 0.5s, downloads from Nx Cloud
6. Task Dependencies
// apps/web/project.json
{
"name": "web",
"targets": {
"build": {
"executor": "@nx/webpack:webpack",
"dependsOn": ["^build"], // Build dependencies first
"outputs": ["{projectRoot}/dist"]
},
"test": {
"executor": "@nx/jest:jest",
"dependsOn": ["build"] // Build before test
}
}
}
# Builds 'ui' library first, then 'web' app
nx build web
7. Affected Commands
# Only test affected projects
nx affected -t test
# Only build affected projects
nx affected -t build
# Show what's affected
nx affected:graph
Use case:
- PR contains changes to
libs/ui nx affected -t testonly testsuiand projects that depend on it- Saves time in CI!
8. Task Orchestration
Run Multiple Tasks
# Run tests in all projects
nx run-many -t test
# Run build then test
nx run-many -t build test
# Parallel execution (default)
nx run-many -t build --parallel=3
Custom Task Pipelines
// nx.json
{
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
"cache": true
},
"test": {
"dependsOn": ["build"],
"cache": true
},
"lint": {
"cache": true
}
}
}
9. Generators
Create custom code generators:
# Generate generator
nx g @nx/plugin:generator my-generator
// tools/generators/my-generator/index.ts
export default async function (tree: Tree, schema: any) {
// Generate files
generateFiles(
tree,
join(__dirname, 'files'),
'libs/new-lib',
{ name: schema.name }
);
// Update config
await formatFiles(tree);
}
# Use generator
nx g my-generator --name=awesome-lib
10. Real-World Example: React Monorepo
# Create workspace
npx create-nx-workspace@latest my-company --preset=react-monorepo
cd my-company
# Generate apps
nx g @nx/react:app web
nx g @nx/react:app admin
# Generate shared libraries
nx g @nx/react:lib ui
nx g @nx/react:lib data-access
nx g @nx/js:lib utils
# Build everything
nx run-many -t build
# Test affected
nx affected -t test
Project structure:
my-company/
├── apps/
│ ├── web/ # Customer-facing app
│ └── admin/ # Admin dashboard
├── libs/
│ ├── ui/ # Shared UI components
│ ├── data-access/ # API calls
│ └── utils/ # Utilities
└── nx.json
11. CI/CD Optimization
GitHub Actions with Nx
name: CI
on: [push, pull_request]
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'npm'
- run: npm ci
# Only test affected
- run: npx nx affected -t test --base=origin/main
# Only build affected
- run: npx nx affected -t build --base=origin/main
With Nx Cloud
- run: npx nx affected -t test --base=origin/main --parallel=3
env:
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
Benefits:
- Distributed task execution
- Remote caching
- Analytics dashboard
12. Migration Guides
From Lerna
npx nx init --integrated
Nx automatically:
- ✅ Keeps your existing structure
- ✅ Adds Nx configuration
- ✅ Provides caching immediately
From CRA (Create React App)
npx nx init
nx g @nx/react:setup-ssr
Summary
Nx supercharges monorepo development:
- Smart caching - never build twice
- Affected commands - only build what changed
- Task orchestration - optimal build order
- Code generation - consistent project structure
- Remote caching - share cache across team
Key Takeaways:
- Computation caching for faster builds
- Affected commands for CI optimization
- Task dependencies for correct build order
- Generators for consistent code
- Works with any npm workspace
Next Steps:
- Try Turborepo
- Setup Monorepo
- Use pnpm
Resources: