通过 Lerna 进行多个软件包的管理
前言
将大型代码仓库分割成多个独立版本化的软件包(package)对于代码共享来说非常有用。但是,如果某些更改 跨越了多个代码仓库的话将变得很 麻烦 并且难以跟踪,并且跨越多个代码仓库的测试将迅速变得非常复杂。
为了解决这些(以及许多其它)问题,某些项目会将 代码仓库分割成多个软件包(package),并将每个软件包存放到独立的代码仓库中。
Lerna
是一种工具,针对 使用 git
和 npm
管理多软件包代码仓库的工作流程进行优化。
入门
1 | npm install --global lerna // 全局安装 lerna |
你的代码仓库目前应该是如下结构:
1 | - hfs-lerna-test/ |
运作方式
Fixed 模式(默认)
固定模式,也就是我们初始化时默认采用的模式。该模式为单版本号,在根目录 lerna.json
中设置,该模式你可以理解为 ‘全量发布’,即任何一个模块更新了,当你在执行 lerna publish
发布时,所有的模块都会统一更新版本号。Babel
目前就是采用该模式。
Independent 模式
lerna init --independent
独立模式的 Lerna 项目允许维护者单独升级包版本,可以理解为’增量发布’。每次发布时,您都会收到有关已更改的每个包的提示,以指定它是补丁、次要、主要还是自定义更改。
这种方式相对第一种来说,更灵活,只需将只需将 lerna.json
中的 version
键改成 independent
即可启用 independent
模式。
创建模块
lerna create test-1
lerna create test-2
执行上面的命令后会在 packages
中创建对应的模块,并根据提示生成 package.json
1 | ├── lerna.json |
依赖管理
- 我们时常看到某些一类诸如
@babel/runtime
、@babel/preset-env
的依赖包,其中babel
实际就是可以看成包组织作用域的意思,代指分将babel
包分割成多个独立版本化的软件包(package)。npm
包前面加@
,代表scopes
相关的包,可以理解为作用域(范围)包,npm
作用域的命名不是谁便就能用的,只有两种可以使用:自己的用户名、自己创建的组织名。- 因此在
test-1
、test-2
中,package.json
的name
字段分别改成@hfs-lerna-test/test-1
,@hfs-lerna-test/test-2
。
在仓库根目录执行指令安装依赖
1 | lerna bootstrap |
lerna bootstrap
,会安装当前目录下所有定义在 package.json
中的依赖包。相当于给 packages
下的每个软件包执行 npm install
如果 test-2/package.json
中引用了test-1
的依赖,执行后将自动将其添加到依赖包中。
1 | "devDependencies": { |
如下:
1 | └── test-2 |
发布模块
lerna publish
- 执行时会打
Tag
,上传Github
,上传NPM
。- 当我们执行
lerna publish
命令时,可能会报错,lerna publish
常见错误见 常见错误类型
lerna publish
本质上还是执行npm publish
,那么我们首先需要在npm
仓库上注册用户,以及推送代码到远程github
仓库。
注意
npm publish
默认发布私有包,想要发布公共包必须使用1
npm publish --acsess=public
复制代码也可以在
packages
下的每个软件包的package.json
中配置1
2
3"publishConfig": {
"access": "public"
},
推动远程
- 登录 Github
- 创建代码仓库,如:
git@github.com:<username>/hfs-lerna-test.git
- 提交代码,推送到指定远程仓库
1 | git init |
登录 npm 账户
1 | # 查看是否登录 |
【发布】使用非组织包方式
使用非组织包方式,需要设置报名为当前 npm
账户名为前缀。
1 | npm adduser |
【发布】组织包 scope packages 方式(推荐)
上诉我们定义的
@hfs-lerna-test
,即代表这里的scope
为@hfs-lerna-test
在 npm 仓库中创建团队,登录 NPM
将自己的账号添加到该团队组织中
最后,可以开始愉快地
lerna publish
了
Lerna 更多命令
1 | lerna init // 初始化 |
lerna
的详细用法,请参考 lerna。
lerna publish 常见错误类型
如
未推送远程仓库
解决:创建
Github
远程仓库,绑定并推送远程。1
2
3$ lerna publish
lerna ERR! ENOREMOTEBRANCH Branch 'master' doesn't exist in remote 'origin'.
lerna ERR! ENOREMOTEBRANCH If this is a new branch, please make sure you push it to the remote first.401 npm 未登录
解决:执行
npm whoami
查看是否NPM
已登录,未登录添加账户或登录。1
2$ lerna publish
lerna ERR! EWHOAMI Authentication error. Use `npm whoami` to troubleshoot.402 您必须注册私人包
解决:当前发布的
npm
包是@
类型为私人包,但是 NPM 上不存在该包组织,或者该组织为公共包。请变更包类型,或者通过共有包发布,详情见 发布模块 - 注意1
2
3$ lerna publish
lerna ERR! E402 You must sign up for private packagesScope
包组织未找到当前发布的
npm
包是@
类型,核对 scope 是否正确,需用自己的用户名、或者自己创建的团队组织名。1
lerna ERR! E404 Scope not found