前言:
目前我是用 Nx 创建大型复杂工程、小工程直接 Vite。
最近在频繁接触到 Monorepo(单一代码仓库):
Monorepo 的概念:是一种软件开发策略,将多个项目或模块存储在一个共享的代码仓库中。
与传统的 多仓库(Polyrepo) 模式不同,Monorepo 通过集中化管理简化依赖关系、版本控制和协作流程。
Monorepo 的核心优势
-
依赖管理:所有项目共享同一依赖版本,避免"依赖地狱"问题。例如,前端和后端项目可以引用同一工具库,确保版本一致性。
-
代码复用:模块或组件可在不同项目间直接引用,减少重复代码。例如,React 组件库可以被多个应用共享。
-
统一工具链:所有项目使用相同的构建、测试和部署工具,降低配置复杂度。
-
原子提交:跨项目的变更可以一次性提交,便于跟踪关联修改。
1、Monorepo 的常见工具
- Lerna:适用于 JavaScript/TypeScript 生态,优化多包管理(如 npm 包)。
- Nx:支持全栈开发(前端、后端、移动端),内置任务调度和缓存。
- Bazel:Google 开源的构建工具,适合超大规模仓库。
- Yarn Workspaces / pnpm Workspaces:通过包管理器实现依赖共享。
适用场景
-
多项目强关联(如微服务架构中的服务端和客户端)。
-
需要频繁共享代码或工具的团队。
-
希望标准化开发流程的企业级项目。
潜在挑战
-
仓库体积:随着时间推移,仓库可能变得庞大,影响克隆和操作速度。解决方案包括部分克隆(Git sparse-checkout)或工具优化。
-
权限控制:需精细化管理代码访问权限(如 Git 子模块或分支策略)。
-
构建时间:全量构建可能较慢。增量构建和分布式缓存(如 Nx Cloud)可缓解此问题。
实施建议
- 渐进式迁移:从少量模块开始,逐步纳入其他项目。
- 明确目录结构:按功能或团队划分目录(如 apps/、libs/)。
- 自动化流程:配置 CI/CD 管道,确保变更后的测试和部署效率。
- 通过合理规划,Monorepo 能显著提升大规模项目的开发效率与协作体验。
那接下来 聊聊 Nx (刚好用到)
2、Nx 构建工具
Nx 构建工具的优势
Nx 是一个高效的现代化构建系统,特别适合管理 Monorepo 项目。其核心优势包括:
高性能增量构建
Nx 通过依赖图分析和缓存机制实现快速增量构建,仅重新编译受影响的部分,显著减少构建时间。
Monorepo 管理能力
内置对多项目 Monorepo 的支持,可轻松管理共享代码库、依赖和工具链,适合大型团队协作开发。
插件生态系统
提供丰富的官方插件(如 React、Angular、Node.js 等),并支持自定义插件扩展功能,简化项目配置。
分布式任务执行
支持将任务分发到多个机器并行执行(需 Nx Cloud),大幅加速 CI/CD 流水线。
开发者体验优化
集成可视化项目依赖图、交互式命令提示和代码生成工具(如 nx generate),降低上手门槛。
Nx 构建工具的局限性
学习曲线
对于小型项目或简单构建需求,Nx 的配置概念可能显得复杂,需要时间掌握其工作流和配置文件结构。
初始配置开销
虽然 Nx 提供了快速初始化模板,但针对特定需求的定制化配置(如自定义构建管道)可能需要额外投入。
生态系统依赖
部分高级功能(如分布式缓存)依赖 Nx Cloud 服务,尽管基础功能可离线使用。
Monorepo 复杂性
若项目规模较小或无需多包管理,Monorepo 模式可能引入不必要的复杂度。
Nx 的典型使用场景
前端大型项目
适合需要统一管理多个应用(如 Web、移动端、后端)的团队,尤其是使用 Angular/React 的技术栈。
全栈开发
通过插件支持前后端项目共存于同一仓库,共享类型定义和工具链,例如结合 Next.js 与 NestJS。
企业级协作
需要严格代码隔离和依赖管理的场景,可通过 Nx 的边界规则(Tagging & Boundaries)强制模块化架构。
微服务原型开发
快速生成多个服务的脚手架,并利用依赖图管理服务间通信。
*------通过权衡其功能复杂度与项目需求,Nx 在中大型项目中往往能显著提升开发效率,而小型项目可能需要评估其必要性。
3、实操
一起创建一个使用 Nx 和 pnpm 管理的多项目工程示例。
我们将创建一个包含一个 React 应用和一个共享库的 Nx 工作区。
步骤概览:
- 环境准备: 确保安装了 Node.js (推荐 LTS 版本) 和 pnpm。
- 创建 Nx 工作区: 使用
create-nx-workspace工具初始化一个新的工作区,并指定使用 pnpm 作为包管理器。 - 添加 React 插件: 为工作区添加对 React 项目的支持。
- 生成应用和库: 使用 Nx 的生成器创建一个 React 应用和一个共享的 TypeScript 库。
- 查看项目结构和依赖图: 了解生成的项目结构,并使用 Nx 的工具查看项目间的依赖关系。
- 运行应用: 启动 React 应用并验证其运行。
实际操作:
1. 创建 Nx 工作区
打开你的终端(命令行工具),然后运行以下命令来创建一个新的 Nx 工作区,并指定使用 pnpm:
bash
npx create-nx-workspace@latest my-nx-workspace --pm pnpm
my-nx-workspace是你的工作区名称,你可以根据需要修改。--pm pnpm指定使用 pnpm 作为包管理器。
执行这个命令时,系统会提示你选择工作区的样式(preset)。为了演示多项目,我们可以选择 apps (Empty workspace - useful for adding projects later on)。
接下来,它可能会问你是否使用 Nx Cloud。Nx Cloud 提供了分布式任务执行和缓存等高级功能,对于初学者或小型项目,可以选择 No。
等待命令执行完成,它会自动为你安装所有必要的依赖。
2. 添加 React 插件
进入你刚刚创建的工作区目录:
bash
cd my-nx-workspace
然后,添加 Nx 对 React 的支持:
bash
pnpm add -D @nx/react
3. 生成应用和库
现在,我们可以使用 Nx 提供的生成器来创建项目。
-
生成一个 React 应用:
bashpnpm nx g @nx/react:app my-react-appnx g是nx generate的简写。@nx/react:app是用于生成 React 应用的生成器。my-react-app是你的应用名称。
生成器会询问一些配置选项,例如:
Which stylesheet format would you like to use?(样式表格式,可以选择CSS、SCSS等)Would you like to add React Router to this application?(是否添加 React Router)Which E2E test runner would you like to use?(端到端测试工具,可以选择Cypress、Playwright或None)
根据你的喜好选择即可。
-
生成一个共享库:
bashpnpm nx g @nx/js:lib shared-utils@nx/js:lib是用于生成通用 TypeScript 库的生成器。shared-utils是你的库名称。
这个库可以用来存放多个应用之间共享的工具函数、类型定义等。
4. 查看项目结构
执行完上述命令后,你的项目结构大致如下:
my-nx-workspace/
├── apps/
│ └── my-react-app/ # 生成的 React 应用
│ ├── src/
│ │ ├── app/ # 应用主要代码
│ │ ├── assets/ # 静态资源
│ │ └── ...
│ ├── project.json # 应用的配置文件
│ └── ...
├── libs/
│ └── shared-utils/ # 生成的共享库
│ ├── src/
│ │ ├── lib/ # 库的主要代码
│ │ └── index.ts # 库的入口文件
│ ├── project.json # 库的配置文件
│ └── ...
├── node_modules/
├── package.json # 工作区的包管理文件
├── pnpm-lock.yaml # pnpm 的锁文件
├── nx.json # Nx 的核心配置文件
└── ...
你可以看到,apps 目录下存放的是应用项目,libs 目录下存放的是库项目。
5. 查看依赖图 (可选)
Nx 可以可视化地展示项目之间的依赖关系。运行以下命令:
bash
pnpm nx graph
这会启动一个本地服务器,并在浏览器中打开一个交互式的依赖图页面,你可以清晰地看到 my-react-app 和 shared-utils 之间的关系(目前可能还没有直接依赖)。
6. 运行应用
最后,让我们运行刚刚创建的 React 应用:
bash
pnpm nx serve my-react-app
nx serve是启动开发服务器的命令。my-react-app是你要启动的应用名称。
执行成功后,终端会显示类似 NX Successfully ran target serve for project my-react-app 的信息,并提示你可以访问 http://localhost:4200 (端口号可能会有所不同)。
打开浏览器访问这个地址,你就能看到你的 React 应用正在运行了!
总结
通过以上步骤,我们成功地使用 Nx 和 pnpm 创建了一个包含 React 应用和共享库的多项目工程。Nx 提供了强大的项目管理和构建能力,使得在大型代码库中维护多个项目变得更加容易。
这个示例只是一个起点,你可以继续探索 Nx 的更多功能,比如:
- 添加更多应用和库: 使用不同的生成器创建 Angular 应用、Node.js 应用、 NestJS 应用或其他类型的库。
- 配置项目依赖: 在
my-react-app中导入和使用shared-utils库中的代码。 - 使用 Nx 的任务执行功能: 例如
nx build、nx test、nx lint等。 - 深入了解 Nx 的缓存和分布式构建: 提升大型项目的构建效率。
--------下面添加一个Vue应用
步骤概览:
- 安装 Vue 插件: 为你的 Nx 工作区添加对 Vue 项目的支持。
- 生成 Vue 应用: 使用 Nx 的 Vue 生成器创建一个新的 Vue 应用。
- 运行 Vue 应用: 启动新创建的 Vue 应用并验证其运行。
实际操作:
假设你已经按照上一个示例创建了 my-nx-workspace 并且位于该目录下。
1. 安装 Vue 插件
你需要先安装 Nx 的 Vue 插件。在你的工作区根目录下运行以下命令:
bash
pnpm add -D @nx/vue
这个命令会将 @nx/vue 插件作为开发依赖安装到你的工作区中,从而让你可以使用 Nx 提供的 Vue 相关生成器和构建工具。
2. 生成 Vue 应用
安装完插件后,就可以使用生成器来创建 Vue 应用了:
bash
pnpm nx g @nx/vue:app my-vue-app
nx g是nx generate的简写。@nx/vue:app是用于生成 Vue 应用的生成器。my-vue-app是你的 Vue 应用名称,你可以根据需要修改。
执行这个命令时,生成器可能会询问一些配置选项,例如:
Which stylesheet format would you like to use?(样式表格式,可以选择CSS、SCSS等)Which E2E test runner would you like to use?(端到端测试工具,可以选择Cypress、Playwright或None)Which unit test runner would you like to use?(单元测试工具,可以选择Vitest、Jest或None)
根据你的项目需求选择合适的选项即可。
3. 查看更新后的项目结构
执行完生成命令后,你的项目结构会更新,apps 目录下会多出一个 my-vue-app 文件夹:
my-nx-workspace/
├── apps/
│ ├── my-react-app/ # 之前创建的 React 应用
│ │ └── ...
│ └── my-vue-app/ # 新创建的 Vue 应用
│ ├── src/
│ │ ├── app/ # Vue 应用主要代码 (通常包含 App.vue, main.ts 等)
│ │ ├── assets/ # 静态资源
│ │ └── ...
│ ├── project.json # Vue 应用的配置文件
│ └── ...
├── libs/
│ └── shared-utils/ # 之前创建的共享库
│ └── ...
├── ... (其他文件)
4. 运行 Vue 应用
现在,你可以像运行 React 应用一样,使用 Nx 来启动你的 Vue 应用:
bash
pnpm nx serve my-vue-app
nx serve是启动开发服务器的命令。my-vue-app是你要启动的 Vue 应用名称。
执行成功后,终端会显示启动信息,并提示你可以访问某个本地地址(例如 http://localhost:4200 或其他端口)。
打开浏览器访问该地址,你就能看到你的 Vue 应用正在运行了!
验证与总结
通过以上步骤,你已经成功地在现有的 Nx + React 工作区中添加了一个 Vue 项目。现在你的工作区同时管理着 React 应用、Vue 应用以及共享库。
Nx 的强大之处在于它允许你:
- 统一管理: 使用相同的命令行工具 (
nx) 来生成、构建、测试、运行不同技术栈的项目。 - 共享代码: 不同框架的应用可以依赖和使用
libs/目录下的共享库。 - 依赖分析: 通过
nx graph可以清晰地看到 React 应用、Vue 应用和共享库之间的依赖关系。 - 独立开发: 每个项目都可以独立开发、运行和构建。
你可以继续探索 Nx 的其他功能,比如在 Vue 应用中使用 shared-utils 库,或者添加更多不同技术栈的项目。希望这能帮助你更好地利用 Nx 构建复杂的多技术栈项目!