JavaScript 单体仓库:代码组织实战
\n\n在 JavaScript (Node.js) 复杂项目的开发中,经常会遇到代码管理的问题。当您拥有多个包、库或微服务,且每个都位于自己的仓库中时,会导致代码重复、版本同步困难以及 CI/CD 速度变慢。解决方案是——单体仓库 (monorepo)。在本文中,我们将探讨如何在实际中组织 JavaScript 单体仓库:从工具选择到构建和发布配置。
\n\n什么是单体仓库以及为什么需要它?
\n\n单体仓库是一种代码管理方法,项目的所有包、库和应用程序都存储在一个仓库中。与多仓库(每个包有自己的仓库)不同,单体仓库提供:
\n\n- \n
- 统一的变更历史:轻松追踪一个部分的更改如何影响另一个部分。 \n
- 代码复用:通用工具和组件位于同一位置,无需发布到 npm。 \n
- 简化的重构:一个包 API 的更改会立即在所有依赖项中可见。 \n
- 统一的 CI/CD 配置:所有包共享一个配置文件。 \n
对于 JavaScript (Node.js) 来说,单体仓库尤其重要,因为它有助于摆脱“依赖地狱”并加速开发。让我们来看一下实际实现。
\n\nJavaScript 单体仓库的工具
\n\n市场上有几种流行的工具。我们将介绍两个主要的:npm workspaces(内置于 npm)和 Lerna(扩展功能)。
1. npm workspaces(内置支持)
\n\n从 npm v7 开始,包管理器支持 workspaces。这是开始使用的最简单方法。项目结构示例:
\n\nmy-monorepo/\n├── packages/\n│ ├── core/\n│ │ ├── package.json\n│ │ └── index.js\n│ ├── utils/\n│ │ ├── package.json\n│ │ └── helpers.js\n│ └── app/\n│ ├── package.json\n│ └── server.js\n├── package.json\n└── lerna.json (可选)\n\n根目录下的 package.json:
{\n "name": "my-monorepo",\n "private": true,\n "workspaces": ["packages/*"]\n}\n\n现在,packages/* 中的所有包都会自动链接。要安装依赖项,只需在根目录下执行 npm install。包之间的依赖关系按标准方式指定:
// packages/app/package.json\n{\n "name": "@my/app",\n "dependencies": {\n "@my/core": "*",\n "@my/utils": "*"\n }\n}\n\nnpm workspaces 在 node_modules 文件夹中创建符号链接,因此导入的工作方式与普通包相同。
2. Lerna(高级管理)
\n\nLerna 是一个用于管理单体仓库的工具,支持发布、版本控制和并行执行脚本。安装:
\n\nnpm install --global lerna\n\n在项目中初始化:
\n\nlerna init\n\nlerna.json 文件:
{\n "version": "independent",\n "npmClient": "npm",\n "packages": ["packages/*"]\n}\n\nindependent 模式允许每个包拥有自己的版本。主要命令:
- \n
lerna bootstrap— 安装依赖项并链接包。 \n lerna run build— 在所有包中执行build脚本。 \n lerna publish— 将更改后的包发布到 npm。 \n
实际代码组织
\n\n让我们看一个为带有 Node.js 后端和通用工具的 Web 应用程序设置单体仓库的示例。
\n\n步骤 1:基本结构
\n\n我们将创建三个包:
\n\n