前言
我的本职工作是一名移动端iOS开发工程师 ,近几年写Flutter
跨端开发较多,因项目需要,接下来我会尝试帮助前端的小伙伴一起写两个微信小程序。
作为一个前端新手 ,我想尝试着为小程序搭建一个MonoRepo架构
,加速项目的开发周期。
在做iOS
开发时,我一直尝试着使用MonoRepo架构开发
,之前也研究过一段时间的Bazel
,因为Bazel
的复杂性,我的调研和尝试总是浅尝辄止,不能深入使用到具体的项目中。
在调研的过程中,了解到在前端项目开发中,MonoRepo
具有天然的优势,这也是我这次想去尝试的一个动机。MonoRepo
到底好不好,适合我们这些小团队使用吗?会加速项目的开发周期吗?带着这些疑问,我也开始了我的MonoRepo
尝试之路
项目介绍
在我们项目需求中,要同时开发两个小程序,一个是患者端 ,一个的医生端 。两个项目要共用非常多的基础components组件
,以及非常多的utils工具
。
传统方案中,我们可以通过npm包
,把一些通用的业务抽离,两个项目去独立引用就可以,但是每次修改,都要通过发布版本,然后在具体的项目引用不同的版本,最后在做调试。
在我们的项目中,除了通过的组件外,一些components
是带着业务逻辑的,如果不能快速验证和引用,对开发体验来说,会大打折扣。并且随着业务的增长,还会有更多的小程序用到这些功能,如果每个项目都独立去搭建和引用,重复工作会大大增加,虽然也可以通过脚手架来完成,但毕竟我不是专业前端开发,还要重新去学习和调研,相比之下,我更愿意去尝试MonoRepo
架构,看看能否满足业务。
MonoRepo 尝试
创建根项目
1、创建new-lerna-workspace2
文件夹
2、通过终端 cd new-lerna-workspace2
到该文件目录中
3、执行 lerna init --packages="packages/*"
Lerna是一个多包管理工具,最初是为了解决跨库调试
的问题,后面衍生出比较多的执行命令方便调试和管理。
按照 lerna 文件组织结构,所有的 package
包都在 packages
目录里,外部只保留 package.json
配置文件即可。package 包是个完整的 npm
项目结构。
通过package.json
中我们得知,项目代码是在一个叫packages
的文件夹下面,但上面的文件目录没有这个文件夹,所有我们手动创建一个名字packages
的文件夹。
创建具体业务项目
1、进入packages
文件夹 通过taro
创建 patient
项目
最初我在选择项目模板时,使用的是React + NutUI
模版,但是在组件编译时,碰到路径编译错误的问题,因为我对taro脚手架创建的项目不熟悉,为了保证验证的稳妥性,我暂时先选择了默认模版,等后续我对前端的认知加深,在尝试使用React + NutUI
模版来验证。
2、进入packages
文件夹 通过taro
创建 doctor
项目
这是目前的一个项目结构,其中patient
和doctor
做为2个小程序主工程,技术架构都采用 Taro + React + NutUI
。那么接下来,我们要创建一个lib库
,这里面包含了2个项目的公共组件和通用业务代码。
创建公共仓库
1、通过lerna crate
创建公共库
2、回到主工程new-lerna-workspace2
目录
3、执行 lerna create lz_components
不知道如何填写,就默认空格就行,等到后续看报错提示,然后在反过来完善资料。
将公共库作为根项目的组建
npm install lz_components
这时重新查看根项目的package.json
,会发现依赖中多了一个依赖包。
将公共库作为子项目的组建
1、cd packages/patient
2、npm install lz_components
在patient 项目中的package.json
文件中, dependencies
依赖项中,多了一个"lz_components": "^0.0.0"
的组件依赖。
3、同理到doctor项目中,也依赖lz_components
组件
编写公共库代码
在子项目中调用组件库
到目前为止,项目运行都是正常的,两个子项目都可以调用到公共组建,并且公共组件在修改时,子项目能马上做出调整。
那么接下来,我们就要做一些不一样的尝试,但更符合工程开发的流程。
doctor项目和patient 引用不同版本的lz_components
设想在版本0.0.0中
javascript
function test_log() {
console.log('I am v0.0.0');
}
在版本0.0.1中
javascript
function test_log() {
console.log('I am v0.0.1');
}
Lerna
支持独立版本管理(independent
),你可以为每个包设置不同的版本。
在 lerna.json
中设置为 independent
:
json
{
"version": "independent",
"packages": [
"packages/*"
]
}
1、创建仓github
仓库,使项目关联该链接仓库,并将代码发布到仓库中
这里面有几个要注意的事项,因为MonoRepo
只有一个仓库 ,所以要把子项目和公共仓库中的.git
文件夹全部删掉 ,确保只有根目录下的.git
文件夹。
2、终端进行npm
登录
因为要进行版本区别,前端框架中,我们使用npm来进行包管理,这时就要先在终端进行npm登录
,然后lerna
会在后续操作中,帮我们把公共组件发到该npm仓库中
。
如果没有npm账号
,请先记得申请一个npm账号。
3、发布npm
在根项目中执行lerna publish --yes --no-git-tag-version
当执行完之后,会让我们选择一个版本升级,根据自己的业务需求,去调整自己升级的规则。
这里还存在一个问题,就是我们的项目没有license,这时我们就要配置项目。
4、在公共组件的package.json中,配置license
遵守规则
5、在项目根目录下,创建LICENSE
文件,并将修改的提交同步到git仓库
6、继续执行lerna publish --yes --no-git-tag-version
每次执行都会询问版本的升级,还是根据自己的需求选择即可。
这里还有一个报错,那就是public npm
包存在lz_components
,此时我们先把包的名字改掉,然后在根项目的package.json
中删除该组件,子项目的package.json
中删除该组件。
删除组件引用后,重新在根目录执行一次 npm install lz_components_test
,子目录也重新执行一次相同的操作。
最终,在根目录执行lerna publish --yes --no-git-tag-version
7、最终效果
log
内容是我随意写的,主要就是为了测试不同的子项目引用不同版本的公共组件,展示不一样的效果。
最后
经过一系列测试,最终实现了通过MonoRepo架构
方式管理代码,并且我做了一些尝试,当我在持续迭代开发时,并不需要频繁的发布版本,那么子项目的代码中,引用本地公共仓库,可以快速实现公共库的开发,工作效率提高不少。
关于 npm、taro、lerna,我介绍的并不多,感兴趣的同学可以自行查阅信息,一些都是前端开发的必备技能。
这是本文的demo地址,感兴趣的小伙伴可以下载查阅,欢迎在留言区探讨交流。
如果你是一个专业的前端开发工程师,欢迎对文章的不足之处进行指正。
后续,在我对前端有一个更深入的了解后,我会对MonoRepo架构
做一个更深层次的挖掘。