TypeScript 单体仓库:为可扩展项目实现高效代码组织
现代应用程序开发通常需要将代码拆分为多个独立的模块或包。此时面临一个两难选择:将每个包存储在单独的仓库(多仓库)中,还是将所有包合并到一个仓库(单体仓库)中。对于 TypeScript 项目,单体仓库成为一个特别有吸引力的解决方案,它提供了类型一致性、简化重构和集中式依赖管理。在本文中,我们将探讨如何组织 TypeScript 单体仓库、配置它并在开发中高效使用。
什么是单体仓库,为什么 TypeScript 需要它?
单体仓库 (monorepo) 是一种将多个项目(包、库、微服务)的代码存储在一个仓库中的方法。在 TypeScript 的背景下,这尤其有用,因为:
- 共享类型和接口: 您可以在一个包中定义共享类型,并在所有其他包中重用它们,避免重复和不同步。
- 统一配置:
tsconfig.json、linter 和格式化工具为整个项目配置一次。 - 简化重构: 更改共享代码或接口会立即反映在所有依赖包上,TypeScript 会提示不一致之处。
- 原子提交: 影响多个包的更改可以通过一次操作提交和推送。
然而,单体仓库需要正确的组织,否则会变成一团乱麻。在 TypeScript 中处理单体仓库的关键工具是 npm/yarn/pnpm workspaces 和 TypeScript Project References。
TypeScript 单体仓库的结构
考虑一个由前端、后端和共享工具库组成的 Web 应用程序的典型单体仓库结构:
my-monorepo/├── packages/│ ├── shared/ # 共享类型、工具、常量│ │ ├── src/│ │ │ └── index.ts│ │ ├── tsconfig.json│ │ └── package.json│ ├── backend/ # 服务器端应用程序(例如 Express)│ │ ├── src/│ │ │ └── app.ts│ │ ├── tsconfig.json│ │ └── package.json│ └── frontend/ # 客户端应用程序(例如 React)│ ├── src/│ │ └── App.tsx│ ├── tsconfig.json│ └── package.json├── tsconfig.base.json # 基础 TypeScript 配置文件├── package.json # 根 package.json (workspaces)└── .gitignore在此结构中:
packages/*— 包含项目所有包的目录。tsconfig.base.json— 所有包继承的通用 TypeScript 配置。- 根目录下的
package.json声明工作空间 (workspaces)。
配置单体仓库:分步指南
1. 初始化根项目并配置 Workspaces
创建根目录和 package.json 文件:
{ "name": "my-monorepo", "private": true, "workspaces": [ "packages/*" ], "scripts": { "build": "npm run build --workspaces", "lint": "eslint packages/*/src --ext .ts,.tsx", "test": "jest" }}"private": true 参数防止意外发布根包。"workspaces": ["packages/*"] 告诉 npm 在哪里查找子包。
2. 创建基础 TypeScript 配置
项目根目录下的 tsconfig.base.json 文件:
{ "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "node", "strict": true, "esModuleInterop": true, "ski