YouTip LogoYouTip

Ts Monorepo

Monorepo is a development pattern that places multiple projects in the same code repository.\\n\\nTypeScript supports Monorepo through project references and toolchains, enabling efficient management of multiple packages.\\n\\n* * *\\n\\n* * *\\n\\n## Why Monorepo is Needed\\n\\nWhen a project contains multiple packages (such as utility libraries, component libraries, applications), the traditional approach requires maintaining multiple code repositories.\\n\\nMonorepo places all packages in the same repository, making code sharing more convenient and version management more unified.\\n\\nTypeScript's project references feature makes type checking and building in Monorepo projects more efficient.\\n\\n> **Concept:** Monorepo (Single Repository) places multiple related projects in the same code repository, facilitating code sharing and coordinated development.\\n\\n* * *\\n\\n## pnpm Workspace\\n\\npnpm is a modern package manager that natively supports Workspace functionality.\\n\\n## Root directory package.json\\n\\n```json\\n{\\n "name": "my-monorepo",\\n "version": "1.0.0",\\n "private": true,\\n // Enable pnpm workspace\\n "packages": [\\n "packages/*"\\n ],\\n // Dev dependency\\n "devDependencies": {\\n "typescript": "^5.0.0"\\n },\\n // script\\n "scripts": {\\n "build": "pnpm -r run build",\\n "clean": "pnpm -r run clean",\\n "type-check": "pnpm -r run type-check"\\n }\\n}\\n\\n> **pnpm:** pnpm's Workspace functionality can automatically link packages under the packages directory together.\\n\\n* * *\\n\\n## Project Structure\\n\\nCreate the directory structure for a Monorepo project.\\n\\n## Directory Structure\\n\\n```text\\nmy-monorepo/\\n β”œβ”€β”€ packages/\\n β”‚ β”œβ”€β”€ utils/ # Utility package\\n β”‚ β”‚ β”œβ”€β”€ src/\\n β”‚ β”‚ β”‚ └── index.ts\\n β”‚ β”‚ β”œβ”€β”€ package.json\\n β”‚ β”‚ └── tsconfig.json\\n β”‚ β”‚\\n β”‚ β”œβ”€β”€ ui-components/ # UI Component package\\n β”‚ β”‚ β”œβ”€β”€ src/\\n β”‚ β”‚ β”‚ β”œβ”€β”€ Button.tsx\\n β”‚ β”‚ β”‚ └── index.ts\\n β”‚ β”‚ β”œβ”€β”€ package.json\\n β”‚ β”‚ └── tsconfig.json\\n β”‚ β”‚\\n β”‚ └── app/ # Applications\\n β”‚ β”œβ”€β”€ src/\\n β”‚ β”‚ └── index.tsx\\n β”‚ β”œβ”€β”€ package.json\\n β”‚ └── tsconfig.json\\n β”‚\\n β”œβ”€β”€ package.json # Root configuration\\n β”œβ”€β”€ tsconfig.base.json # Base configuration\\n └── pnpm-workspace.yaml # pnpm Configuration\\n\\n> **packages:** All packages are placed under the packages directory, and each package has its own independent package.json and tsconfig.json.\\n\\n* * *\\n\\n## Base TypeScript Configuration\\n\\nCreate a base configuration for all packages to use.\\n\\n## tsconfig.base.json\\n\\n```json\\n{\\n // Compiler options\\n "compilerOptions": {\\n // Target version\\n "target": "ES2020",\\n // Module system\\n "module": "ESNext",\\n // Strict Mode\\n "strict": true,\\n // Skip Library Type checking\\n "skipLibCheck": true,\\n // Enable ES module interop\\n "esModuleInterop": true,\\n // Enforce file name casing consistency\\n "forceConsistentCasingInFileNames": true,\\n // Module resolution\\n "moduleResolution": "bundler",\\n // Resolve JSON modules\\n "resolveJsonModule": true,\\n // Isolated modules\\n "isolatedModules": true,\\n // Do not generate output files\\n "noEmit": true\\n }\\n}\\n\\n> **Inheritance:** Each package's tsconfig.json inherits the base configuration, only overriding options that need customization.\\n\\n* * *\\n\\n## Utility Package Configuration\\n\\nConfigure TypeScript for the utility package.\\n\\n## packages/utils/tsconfig.json\\n\\n```json\\n{\\n // Inherit Base configuration\\n "extends": "../../tsconfig.base.json",\\n // Compiler options\\n "compilerOptions": {\\n // Output directory\\n "outDir": "./dist",\\n // Declaration file directory\\n "declarationDir": "./dist/types",\\n // Generate declaration files\\n "declaration": true,\\n // Generate declarations for entry files\\n "declarationMap": true,\\n // Module export style\\n "module": "ESNext",\\n // Enable Project references\\n "composite": true\\n },\\n // Included files\\n "include": ["src/**/*"],\\n // Excluded files\\n "exclude": ["node_modules", "dist", "**/*.test.ts"]\\n}\\n\\n> **composite:** After enabling project references, TypeScript can incrementally compile this package.\\n\\n* * *\\n\\n## Application Configuration\\n\\nConfigure TypeScript for the main application and reference other packages.\\n\\n## packages/app/tsconfig.json\\n\\n```json\\n{\\n // Inherit Base configuration\\n "extends": "../../tsconfig.base.json",\\n // Compiler options\\n "compilerOptions": {\\n // Output directory\\n "outDir": "./dist",\\n // JSX Configuration\\n "jsx": "react-jsx",\\n // Path alias\\n "baseUrl": ".",\\n "paths": {\\n "@my-utils/*": ["../utils/src/*"],\\n "@my-ui/*": ["../ui-components/src/*"]\\n }\\n },\\n // Project references\\n "references": [\\n { "path": "../utils" },\\n { "path": "../ui-components" }\\n ],\\n // Included files\\n "include": ["src/**/*"],\\n // Excluded files\\n "exclude": ["node_modules", "dist"]\\n}\\n\\n> **Path Aliases:** You can configure path aliases to directly reference other packages in the same repository.\\n\\n* * *\\n\\n## Dependencies Between Packages\\n\\nDeclare dependencies on packages within the same repository in package.json.\\n\\n## packages/app/package.json\\n\\n```json\\n{\\n "name": "@my-org/app",\\n "version": "1.0.0",\\n "private": true,\\n "dependencies": {\\n // Reference packages from the same repository\\n "@my-org/utils": "workspace:*",\\n "@my-org/ui-components": "workspace:*",\\n // External dependencies\\n "react": "^18.2.0",\\n "react-dom": "^18.2.0"\\n },\\n "devDependencies": {\\n // Dev dependency\\n "@types/react": "^18.2.0",\\n "typescript": "^5.0.0"\\n }\\n}\\n\\n> **workspace:** Use workspace:* to point to other packages in the same repository; pnpm will resolve them automatically.\\n\\n* * *\\n\\n## Build Scripts\\n\\nCreate unified build scripts for the Monorepo.\\n\\n## Root directory package.json\\n\\n```json\\n{\\n "scripts": {\\n // Build all packages\\n "build": "pnpm -r run build",\\n // Clean all build artifacts\\n "clean": "pnpm -r run clean",\\n // Type checking\\n "type-check": "pnpm -r run type-check",\\n // Test all packages\\n "test": "pnpm -r run test",\\n // Incremental build\\n "build:watch": "pnpm -r --parallel run build:watch",\\n // Launch App\\n "dev": "pnpm --filter @my-org/app run dev"\\n }\\n}\\n\\n> **pnpm -r:** Recursively executes scripts with the same name in all packages.\\n\\n* * *\\n\\n## Precautions\\n\\n* **Package Naming Convention:** Use the @org-name/package format\\n* **Independent Versioning:** Each package can be versioned independently\\n* **Workspace Protocol:** Use workspace:* to reference packages in the same repository\\n* **Build Order:** Depended-upon packages need to be built first\\n\\n> **Best Practices:** Monorepo is suitable for managing multiple related projects, which can significantly improve code reuse and development efficiency.\\n\\n* * *\\n\\n## Summary\\n\\nMonorepo is the recommended pattern for modern frontend project management.\\n\\n* **pnpm Workspace:** Natively supports Monorepo\\n* **Project References:** Enables incremental compilation\\n* **Path Aliases:** Conveniently references packages in the same repository\\n* **Unified Management:** Shares configuration and dependencies\\n\\n> **Suggestion:** When a project contains multiple related packages, consider the Monorepo approach first.
← Ts PerformanceTs Paths β†’