MonoRepo实战:pnpm+nx搭建MonoRepo项目
背景
之前有写过几篇关于monorepo的文章,具体如下:
再次复习一下MonoRepo
的概念:
Monorepo是包含多个不同项目的单一存储库,且不同项目之间具有明确定义的关系。
之前大多数是理论知识,能让我们知道pnpm
和nx
是什么,但是具体要到项目实战就有点懵,不知道从而下手,下面我们就一步步开始搭建pnpm
+nx
的Monorepo仓库。
PS:这里将会从已有项目中去开始踩坑,这里用的是之前做一个node-gptcommit命令行工具+一个chrome插件,将两个项目放到一个Monorepo仓库去管理。
项目初始化
第一步,项目结构调整
先来看看原先node-gptcommit
项目结构:
1 | node-gptcommit |
再看一下node-gptcommit-chrome
项目的目录结构:
1 | node-gptcommit-chrome |
接下来我们把项目结构做一下调整,将两个项目的代码挪到packages
目录下,同时在新项目中初始化npm init
,大概结构如下:
1 | node-gptcommit |
第二步,项目初始化
前提条件准备:
- 安装全局
pnpm
- 升级node版本到16.19.0+,这里可以通过pnpm去管理node版本
1 | # 先安装全局pnpm 后续需要根据pnpm + workplace去管理 |
2.1 创建pnpm workplace
- 新建
pnpm workplace
工作空间文件pnpm-workspace.yaml
,具体如下:
1 | packages: |
- 子项目互相依赖的时候,可以通过
workplace:
协议去设置依赖,支持一下几种写法:
“npm_name”: “workplace: *”
所有版本都依赖本地工作空间“npm_name”: “workplace: npm_name@1.0.0”
指定版本写法“npm_name”: “workplace: ../npm_name”
相对路径写法
因此apps
中的应用层加入对公共库libs
的依赖,如在apps/node-cli
将
1 | { |
- 子项目中需要对
package.json
中的scripts
中做统一管理,如下:
1 | { |
2.2 引入nx
,实现按序打包
- 全局安装和在项目根目录下安装
nx
1 | # 全局安装方便后面调试项目使用 |
nx
在monorepo
架构中里主要解决几个问题:
- 解决项目中互相依赖问题,就是构建顺序问题,其任务流有点像管道的概念
- 解决项目中打包缓存问题,比如:一些公共包没有多大变动,就不需要再次打包
- 提供一些快捷工具快速引入一个子项目或公共包
还需要转变一个观点:
重要提示:nx会接手项目的所有打包流程,因此所有相关的命令都由nx进行触发
- 自动生成的
nx.json
解析认知 ,
1 | { |
nx.json
主要用来配置子项目的构建顺序和控制缓存,比如:
- 构建顺序:在项目中
apps
进行build
操作时候会依赖libs
项目中的build
,就可以在targetDefaults
中配置"dependsOn": ["^build"]
,举个例子:- 当
apps
的子项目node-cli
在运行build操作 - 会提前将依赖的
libs
中的summarize
子项目也进行build
- 当
- 控制缓存:提高构建速度,利用缓存,但是有时候我们并不需要每个构建命令都去缓存,这个时候就可以用
tasksRunnerOptions
中的cacheableOperations
去控制
nx.json
的其他详细配置可以到官网中查看nx.json。
- 调整根目录
package.json
中scripts
,后续将采用nx
去进行分发构建任务:
1 | { |
- nx一些命令工具,如使用
nx graph
可以看到Monorepo中子项目相互依赖情况,如下图所示:
更多使用命令,可以到官网查看:nx命令脚本
总结
到了这里,我们完成Monorepo基本架构的搭建,后续工作就依据不同的业务或代码进行重设计代码结构。
Monorepo架构有个很明显好处,就当你的项目需要新增一个子项目或者依据现有的功能进行剥离成功公共组件,将会很轻松就实现。比如说,当我的node-gptcommit需要新增一个桌面端,那么我就可以根据现有的libs库快速开发完成。
在pnpm
+nx
搭建Monorepo项目中,我们可以学习到几个点:
- 使用
pnpm
替代yarn
或npm
管理node_modules
,不仅快,而且会比较稳定,因为它不允许代码引入一些未在package.json
使用的npm
包 - 使用
pnpm
同时支持一些libs
被其他apps的子应用依赖,如:"@node-gptcommit/git-utils": "workplace: *”
nx
在使用上会需要一些门槛,尤其需要理解其中几个点:- 第一,子项目互相依赖,
nx
可以在build构建的时候将另外一个包也同时build构建 - 第二,
nx
会取代掉我们平时在根目录使用yarn build
或npm build
的习惯,而是采用nx build
- 第三,
nx
提供一些常用的命令行,如:nx graph
能让我们快速解决Monorepo架构常见的依赖问题
- 第一,子项目互相依赖,
本博文项目Github源码地址: node-gptcommit
参考资料
- 本文作者: Qborfy
- 本文链接: https://www.qborfy.com/today/20230225.html
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!