简介:本篇主要介绍lerna 4如何升级到lerna 6,以及lerna 6与lerna 4中存在的一些差异,最后介绍了lerna结合CI场景去发布多包项目
背景
多包项目一直用的是lerna
4版本,但是最近在lerna
4中直接使用pnpm
在本地没有什么大问题,但是在CI场景发布的时候,无法正常publish
包,会报错,于是,我们进行了排查,并记录了这个过程以及最终结果。
lerna 4与6 中使用pnpm
lerna 4使用 pnpm 抛错
当我们直接在lerna
4中使用pnpm
可能会碰到如下错误
- 测试用例无法正常跑通
- CI场景出现
ERR_PNPM_OUTDATED_LOCKFILE
错误 - CI场景出现
EUNCOMMIT working tree has uncommitted changes
错误
具体的错误详情如下所示
测试用例无法正常跑通
测试用例无法正常跑通,提示找不到子包内的依赖
CI场景-ERR_PNPM_OUTDATED_LOCKFILE错误
CI场景执行pnpm install
的时候出现ERR_PNPM_OUTDATED_LOCKFILE
错误
原因:是因为包之间有依赖关系的话,子包在
lerna
修改版本号的时候,package.json
是变化了的,所以package.json
与pnpm.lock
文件对不上,报错是正常的
CI场景- EUNCOMMIT working tree has uncommitted changes
CI场景执行lerna publish
的时候出现EUNCOMMIT working tree has uncommitted changes
错误
加上
pnpm install --no-frozen-lockfile
,install
是正常了,但是publish
的时候,还是会抛错,提示working tree
有未提交的文件,所以发布还是不成功,原因是install
的时候,因为子package的版本号变了,install之后lock文件发生了更新,所以git tree又有未提交文件
然后去lerna项目内找了相关issues,发现lerna
4确实不支持pnpm
,相关的issuesQuestion: moving from yarn to npm,可以从pnpm support看到相关进度在2022年的时候正式支持
lerna 6使用 pnpm 正常
lerna 4迁移到lerna 6
步骤如下
第一步:在根目录下添加pnpm-workspace.yaml
内容如下所示
packages:
- packages/* # 这里写自己的多包文件目录
第二步:lerna.json
内将useWorkspaces: true
第三步:将package.json
内的lerna
版本升至6.x
第三步:使用pnpm
的命令替换lerna
的bootstrap, link, and add
命令,如下所示
注意在lerna
6中直接使用bootstrap
、add
、link
命令,会报pnpm is not supported
错误,如下所示
lerna bootstrap
lerna notice cli v6.6.1
lerna ERR! EWORKSPACES Bootstrapping with pnpm is not supported. Use pnpm directly to manage dependencies: https://pnpm.io/cli/install
lerna add md5 --scope=@xxx/lerna-demo-core
lerna notice cli v6.6.1
lerna ERR! EPNPMNOTSUPPORTED Add is not supported when using `pnpm` workspaces. Use `pnpm` directly to add dependencies to packages: https://pnpm.io/cli/add
原因是
block usage of bootstrap, link, and add commands. Instead, you should use pnpm commands directly to manage dependencies (pnpm.io/cli/install).
直接使用pnpm
的相关的命令即可,不在使用bootstrap
等命令
注意通过pnpm add
添加依赖看到的是workspace:xxx
这种写法,这个是正常的,最终publish
的时候会替换成对应的版本号
"dependencies": {
"@xxx/lerna-demo-utils": "workspace:0.1.0-beta.17",
"@xxx/uid": "^0.0.1-beta.2",
"axios": "^0.26.0",
"fetch": "^1.1.0",
"qs": "^6.11.1"
},
在看下使用lerna version
之后提交的commit
内,发现commit
内主动更新了pnpm.lock
文件
再看CI
场景正常
lerna中使用yarn与pnpm命令对比
场景/包管理工具 | yarn | pnpm |
---|---|---|
首次安装依赖 | lerna bootstrap | yarn install | pnpm install |
根目录下安装依赖 | yarn add md5 -w | pnpm install md5 -w |
某个子包安装依赖 | lerna add md5 --scope=child1 | |
lerna add md5 --scope= @xxx/lerna-demo-core | pnpm add md5 --filter child1 | |
pnpm add md5 --filter @xxx/lerna-demo-core | ||
所有子包安装依赖 | lerna add md5 | pnpm add md5 --filter "child*" |
pnpm add qs --filter '@xxx/*' |
除了上面的区别,lerna
6相对lerna
4还有一个比较大的变动点就是通过nx
提供了更强的调度模型与缓存方式,可以在lerna.json
内通过"useNx": false,
参数来进行关闭
CI场景-lerna ERR! EUNCOMMIT M pnpm-lock.yaml
原因:
pnpm
不同版本之间,生成的pnpm-lock.yml文件有差异feat!: lockfile format v6
解决:将本地的
pnpm
版本与CI场景的pnpm
版本保持一致
借助CI场景发布npm包
获取npm token
第一步:进入npm官网
第二步:进入Access Tokens
页面-选择Claasic Token
第三步:选择Automation
-点击Generate Token
第四步:保留创建好的
token
,留到后面的步骤用
不同的CI工具结合lerna发布npm包
gitlab CI中结合lerna发布npm包
第一步:新增.gitlab-ci.yml
文件
第二步:配置.gitlab-ci.yml
文件
stages:
- publish
publish:
stage: publish
image: node:v16.13.1
script:
- echo -e $NPM_AUTH_CONTENT >> ~/.npmrc # 注入 token
- pnpm install --frozen-lockfile --registry=https://registry.npmmirror.com # 安装依赖
- yarn build # 构建
- yarn publish-all # 发布
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
changes:
- package.json
- lerna.json
- packages/**/package.json
when: always
publish-beta:
stage: publish
image: node:v16.13.1
script:
- echo -e $NPM_AUTH_CONTENT >> ~/.npmrc # 注入 token
- pnpm install --frozen-lockfile --registry=https://registry.npmmirror.com # 安装依赖
- yarn build # 构建
- yarn publish-all --pre-dist-tag=beta # 发布 beta 版本
rules:
- if: '$CI_COMMIT_BRANCH == "beta"'
changes:
- package.json
- lerna.json
- packages/**/package.json
when: always
第三步:在gitlab
界面配置环境变量,注入token
github action结合lerna发布npm包
第一步:新增.github/workflows/npm-publish.yml
文件
第二步:配置npm-publish.yml
文件
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
name: Node.js Package
# 可以自己根据条件自定义触发action的条件
on:
push:
paths:
- '**/package*.json'
workflow_dispatch:
jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # 一定要设置,不然获取不到tag,无法正常publish
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm install pnpm -g
- run: pnpm install --registry=https://registry.npmmirror.com
- run: npm run build
- run: npm run publish-all
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} # 注入的npm token
第四步:在github setting
配置npm token
进入项目setting
配置
点击添加secret
变量
填写key
与value
,value
就是在npm
通过Claasic Token
获取到的token
添加成功之后,就能看到对应的key
总结
上面提供的示例或者碰到的错误,并不一定覆盖了所有场景,只是列出来自己升级过程中碰到的问题,具体的问题还需要具体分析,最后提供了一个lerna-demo项目,可以直接查看