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)+ 按序构建(项目引用)",三者齐备后,跨包开发就像写单个项目一样顺畅。