使用TypeScript的Monorepo:代码组织实战
\n\n在现代Web开发中,尤其是在使用TypeScript时,开发者经常面临一个两难选择:将所有代码存储在一个仓库(monorepo)中,还是将其分割成多个小型仓库(多仓库)。对于中大型项目,当代码复用和统一配置至关重要时,monorepo已成为事实上的标准。在本文中,我们将探讨如何正确组织基于TypeScript的monorepo,从基本结构到高级技术。
\n\n什么是Monorepo,为什么需要它?
\n\nMonorepo是一种将多个项目(包、库、应用)的代码存储在一个仓库中的方法。在TypeScript的上下文中,这尤其方便,因为它允许:
\n\n- \n
- 重用类型和接口,无需发布到npm即可在系统的不同部分之间共享。 \n
- 简化重构:一个包中的更改会自动在所有依赖包中验证。
- 拥有统一的配置,用于linter、格式化程序和构建工具。
- 简化CI/CD:一个仓库对应一个流水线。
在TypeScript中处理monorepo的流行工具包括Nx、Turborepo和npm/yarn/pnpm workspaces。我们将采用pnpm workspaces和TypeScript项目引用的方法,因为这是一套最小且灵活的方案。
\n\nMonorepo结构:基本配置
\n\n让我们为TypeScript项目创建一个典型的monorepo结构。假设我们有三个包:core(通用类型和工具)、server(后端)和web(前端)。
1. 根配置
\n\n从项目根目录开始。创建一个包含workspace的package.json文件:
{\n "name": "my-monorepo",\n "private": true,\n "workspaces": [\n "packages/*"\n ],\n "scripts": {\n "build": "tsc -b",\n "clean": "tsc -b --clean",\n "lint": "eslint packages/*/src"\n }\n}\n\n\n然后配置根tsconfig.json。使用项目引用——这是TypeScript针对monorepo的关键特性:
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "strict": true,\n "composite": true,\n "declaration": true,\n "declarationMap": true,\n "sourceMap": true,\n "outDir": "./dist",\n "rootDir": ".",\n "skipLibCheck": true\n },\n "references": [\n { "path": "./packages/core" },\n { "path": "./packages/server" },\n { "path": "./packages/web" }\n ]\n}\n\n\n重要提示:对于其他包引用的包,composite: true选项是必需的。它启用增量构建并生成.d.ts文件。
2. 配置core包
\n\n进入packages/core目录。创建package.json:
{\n "name": "@my/core",\n "version": "1.0.0",\n "main": "dist/index.js",\n "types": "dist/index.d.ts",\n "scripts": {\n "build": "tsc -b"\n }\n}\n\n\n以及该包的tsconfig.json:
{\n "extends": "../../tsconfig.json",\n "compilerOptions": {\n "outDir": "./dist",\n "rootDir": "./src"\n },\n "include": ["src"]\n}\n\n\n创建一个简单的模块src/index.ts:
export interface User {\n id: string;\n name: string;\n email: string;\n}\n\nexport function greet(user: User): string {\n return `Hello, ${user.name}!`;\n}\n\n\n现在包
博客
书籍推荐
推荐阅读