TypeScript Monorepo 配置

Monorepo 指在同一个仓库中管理多个包(package)。TypeScript 生态里,Monorepo 通常 = pnpm/yarn 的 workspace(软链依赖)+ TypeScript 项目引用(按序构建),改动一个包即可联动构建所有依赖它的包。

为什么用 Monorepo

多包同仓便于共享代码、统一发布与 CI;难点是依赖关系与构建顺序复杂。TypeScript 的 paths、references 与 workspace 软链恰好解决"跨包导入"与"构建顺序"两大难题。

目录结构与工具

推荐 pnpm workspace + tsc -b,典型结构如下:

my-monorepo/
├─ package.json          # 根:private + workspaces 声明
├─ pnpm-workspace.yaml
├─ tsconfig.base.json    # 共享编译配置
└─ packages/
   ├─ core/              # 被依赖的底层包
   └─ app/               # 依赖 core 的应用

pnpm-workspace.yaml 声明包目录:

packages:
  - "packages/*"

共享 tsconfig.base.json

公共编译选项抽到根目录,各子包通过 extends 继承,避免重复维护:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "composite": true,
    "skipLibCheck": true
  }
}

子包只需覆盖出入口:

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": { "rootDir": "src", "outDir": "dist" }
}

跨包依赖与项目引用

core 里导出能力,根 tsconfig 用 references 声明全部子包:

// packages/core/src/index.ts
export const name = "core";
export function greet(who: string): string {
  return `Hello ${who} from ${name}`;
}
// 根 tsconfig.json
{
  "files": [],
  "references": [{ "path": "./packages/core" }, { "path": "./packages/app" }]
}

在 app 中按包名导入并享受类型提示(前提:core 的 package.json 声明了包名与入口 "main": "./dist/index.js",且 pnpm 已建立软链):

import { greet } from "@demo/core"; // workspace 软链解析到 core
console.log(greet("TS"));           // 输出:Hello TS from core

构建与日常命令

一条命令按依赖顺序构建全部子包:

pnpm install   # 首次安装并建立 workspace 软链
tsc -b         # 根目录按 references 顺序增量构建
tsc -b -w      # 监听模式开发

小结

Monorepo 的关键是"共享配置(extends)+ 软链依赖(workspace)+ 按序构建(项目引用)",三者齐备后,跨包开发就像写单个项目一样顺畅。

笔记加载中…