🚀🚀🚀Lerna通关秘籍🔥🔥🔥
“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情”
简介
Lerna 是一个用于快速管理和发布同一仓库下多个 package
包的管理工具,它基于 git
与 npm
。
初始化lerna工程
首先,我们新建一个目录(yd-lerna-dev
),然后初始化项目的 package.json
文件:
npm init -y
接着,安装 lerna
:
npm i lerna -D
也可以进行全局安装:
npm i -g lerna
然后,初始化 lerna
:
lerna init
执行命令后,会自动创建 packages
目录并生成 lerna.json
文件:
{
"version": "1.0.0", // 版本号
"packages": [ // 指定子包所在的目录
"packages/*"
]
}
增加LICENSE文件
初始化完工程后,我们给这个项目增加一个项目许可证,这个是一定要增加的,要不后续发布流程走不通。
在根目录下创建 LICENSE
文件:
MIT License
Copyright (c) 2021 橙某人
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
顺道也增加 .gitignore
文件:
node_modules/
lerna.json
{
"useWorkspaces": true, // 是否使用 workspaces 的配置; 如果为 true, 将会使用 package.json 文件的 "workspaces" 属性, 而下面的 "packages" 属性将不会生效
"version": "0.0.0", // 所有子包的版本号; 两种模式: 固定模式(x.x.x)、独立模式(independent)
"npmClient": "npm", // 指定运行命令的客户端; 可以设置为 npm/cnpm/yarn/pnpm 等等
"packages": [ // 指定子包所在的目录, 可以指定多个
"packages/*"
],
"command": {
// lerna publish 命令的相关配置
"publish": {
"ignoreChanges": [ // 指定那些目录或者文件的变更不会被publish
".gitignore",
"*.log",
"*.md"
],
"message": "chore(release): publish", // 执行发布版本更新时的自定义提交消息
"registry": "https://npm.pkg.github.com" // 设置npm包发布的注册地址
},
// lerna bootstrap 命令的相关配置
"bootstrap": {
"ignore": "npm-*", // 设置执行 lerna bootstrap 安装依赖时不受影响的包
"npmClientArgs": [ // 指定在执行 lerna bootstrap 命令时传递给 npm install 的参数
"--no-package-lock"
],
"scope": "" // 指定那些包会受 lerna bootstrap 命令影响
},
// lerna version 命令的相关配置
"version": {
"allowBranch": "", // 指定分支
"conventionalCommits": true
}
}
}
Lerna
的配置文件分为两种文件,可以是 lerna.json
或者是 nx.json
文件。传送门
两种版本处理模式
Lerna
对于子包版本号的处理方式有两种模式,分别是固定模式(x.x.x
)与独立模式(independent
)。
固定模式(x.x.x
)
所有子包的版本号都是统一的,每次升级发布,子包的版本都统一更新,不管这个子包内容是否有更改过。
使用这种模式的方式就是在 lerna.json
配置文件中,写死一个固定版本号:
{
"version": "x.x.x"
}
独立模式(independent)
所有子包的版本号都是独立的,在 lerna publish
发布时,只会更新有变化的子包版本号。
而使用这种模式需要把 version
字段改成 independent
:
{
"version": "independent"
}
核心命令
lerna init
该命令用于初始化 Lerna
工程。
此命令可以接收一个参数,让工程使用独立的版本控制模式。
lerna init --independent
// or
lerna init -i
执行后 lerna.json
文件:
{
"version": "independent",
"packages": [
"packages/*"
]
}
lerna create
该命令用于在 Lerna
工程中创建一个子包。
我们先给上面初始化的 Lerna
工程增加两个子包,分别执行以下命令:
lerna create button
(不断回车即可)
lerna create icon
执行后的目录结构如下:
然后修改子包的 package.json
文件:
{
"name": "@yd-lerna-dev/button",
...
}
{
"name": "@yd-lerna-dev/icon",
...
}
主要就是把 name
字段修改一下,这是我们最终要发布到 npm
的名称,为了不引起名称占用的冲突,我们加个了 npm
组织前缀(@yd-lerna-dev/xxx
)。
lerna publish
该命令用于把需要发布的包上传到 npm
上。
当然,现在我们还不能把包上传到 npm
上,上传之前我们还需要做一些准备工作。
新建远程仓库
首先,先要创建 git
仓库,开头我们就讲过 Lerna
是基于 git+npm
的,你也可以尝试执行下图中的命令, 会报错,但 Lerna
的提示还是很友好的。
创建 git
仓库,你可以选择去 github
或者 gitee
等等平台创建,反正最终获取到一个 xxx.git
的仓库地址即可。
然后你需要把代码提交到远程仓库中,你可以借助 vscode
等编辑器工具来提交代码,或者通过以下命令来提交。
git add .
git commit -m "init commit"
git push --set-upstream origin master
对
git
命令还不熟悉的小伙伴,可以看看小编的另一篇文章,它能帮助你把git
玩得明明白白(✪ω✪)。
创建npm组织
提交完代码后,我们需要做另外一件事情,就是在 npm 平台上创建自己的组织。
为什么需要做这件事情呢?原因是因为在上面我们修改了每个子包的 package.json
文件的 name
字段,给它们都分别加上了组织前缀(@yd-lerna-dev/xxx
)。当然,如果你能给每个子包的名称命名是唯一的,那么你也可以不加组织前缀,也不用创建组织,直接发布包到 npm
上就可以了。(可以跳过这一步骤)
小编还是推荐使用组织前缀,这样子完全不用考虑自己的 npm
包可能会和别人的包命名冲突的问题,而且在下载安装的时候,也会展示成比较可阅读的形式,如下:
"devDependencies": {
"@yd-lerna-dev/button": "^1.0.0",
"@yd-lerna-dev/icon": "^1.0.0",
"@vue/cli-plugin-babel": "^1.0.0",
"@vue/cli-plugin-eslint": "^1.0.0",
}
那么,我们继续来创建自己的 npm
组织,其实挺简单的。
先登录你的 npm 进到官网,然后点击个人中心里的创建组织按钮。
输入组织名称,小编这里的组织叫 yd-lerna-dev
,然后点击创建。
很简单就创建成功了。
修改子包package.json
然后我们需要把所有子包都改成公共的属性。
// icon/package.json
{
"name": "@yd-lerna-dev/icon",
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
...
}
主要就是修改子包 package.json
文件中的 publishConfig
字段。
登录npm
在最后上传之前,我们需要让本地的环境登录一下 npm
。
npm login
执行以上命令,输入账号、密码还有邮箱就可以了,可能还需要邮箱的验证码,可以打开自己的邮箱查看。
![]()
如果你遇到以上错误,可以试试重新登录一下
npm
。
发布
最后我们回到项目中,执行 lerna publish
命令。
执行后会提示让你选择版本号,你可以选择想要发布的版本号,也可以自定义版本号。
在最终发布的时候,也会再次询问你,并列出子包的版本号变化。
当你能看到以下画面,就说明你发布成功了。
你也可以在 npm
平台上查看你的包。
independent模式发布
我们来试试如果使用 independent
模式进行发布又会发生什么呢。
先修改 lerna.json
文件:
{
"version": "independent",
"packages": [
"packages/*"
]
}
然后我们随便修改一个 packages/icon
子包的内容。
提交代码:
git add .
git commit -m "update icon"
git push
然后执行发布命令:
选择版本号后,你会看到,这个时候就不是统一更新子包版本号了,只有变更内容的子包才会重新发布。
当然,如果你更改多个子包,那么也会让你一个一个选择,真的是很方便呢(⁎˃ᴗ˂⁎)。
lerna version
该命令用于给远程仓库最新更改提交的代码打上一个 tag
版本号。
对
tag
还不了解的小伙伴可以先去了解一下和 git tag 相关的内容。
我们可以去到远程仓库的平台上查看我们每次执行 lerna publish
命令后产生的标签情况。
通过 lerna publish
命令产生的标签是和你在 npm
上发布的版本号是同步的,因为它俩是同步进行的。
那么,如果我只想把最新修改提交的代码先打上一个 tag
,但又不想它立马就同步发布到 npm
上,那么你就可以使用以下命令。
lerna version
执行命令后,你会发现远程仓库会增加相应的标签,但是 npm
上并没有发布新版本。
可能这里有小伙伴会在想,那它和通过
git tag
直接创建的标签是不是一样的?一半一半,对于远程仓库来说,标签是一样的;但是对于执行命令来讲,又是有点区别的,通过lerna version
打上tag
的代码,再次执行lerna publish
是无法被检测到的.而
git tag
则反之。
lerna add
该命令用于给子包添加依赖。
给所有子包都添加依赖:
lerna add vue
给某个子包单独添加依赖:
lerna add lodash --scope=@yd-lerna-dev/button
默认依赖是安装在 dependencies
,也可以添加通过参数配置(--dev/--peer
),安装到 devDependencies/peerDependencies
或者 。
lerna add jquery --scope=@yd-lerna-dev/button --dev
lerna clean
该命令用于清除子包的依赖。
清除所有子包的依赖:
lerna clean
需要注意的,这个命令只会把子包里面的 node_modules
删除,但是 package.json
里面的依赖信息还是存在的。
清除某个子包的依赖:
lerna clean --scope=@yd-lerna-dev/button
lerna bootstrap
该命令用于给子包重新安装依赖。
给所有子包重新安装依赖:
lerna bootstrap
给某个子包单独重新安装依赖:
lerna bootstrap --scope=@yd-lerna-dev/button
lerna link
该命令用于将 Lerna
工程内的子包进行相互引用。
我们来修改子包 @yd-lerna-dev/button
的 package.json
文件:
{
"name": "@yd-lerna-dev/button",
"dependencies": {
"@yd-lerna-dev/icon": "^0.1.6"
}
...
}
让它依赖另一个子包,然后执行 lerna link
命令。
你会发现在 @yd-lerna-dev/button
子包的 node_modules
中会多了一个包的引用,你可以在子包内随意使用它。
这里你可能会在想,那我通过 lerna add
一样也能实现子包引用另一个子包吧?
是的。但是 lerna link
的优势在于它是实时的,你在 @yd-lerna-dev/icon
子包中修改的内容,可以实时反应到 @yd-lerna-dev/button
子包的引用中去,不用去发布,这就极大的提高我们的开发效率了。
如果对 npm link 熟的小伙伴就会发现它们俩挺类似的。
lerna run
该命令用于执行子包中的 script
命令。
执行所的子包的 script
命令:
lerna run <scriptName>
执行某个子包的 script
命令:
{
"name": "@yd-lerna-dev/button",
"scripts": {
"test": "echo \"Hello Lerna - button\""
},
...
}
随便修改一下 package.json
文件的 script
命令,打印点东西,然后执行以下命令:
lerna run --scope @yd-lerna-button test
lerna exec
该命令用于在子包中执行任意命令。
在所有子包中执行删除 node_modules
命令:
lerna exec -- rm -rf ./node_modules
(需要注意 rm -rf
命令并不能直接在 window
系统下执行)
在某个子包中执行删除 node_modules
命令:
lerna exec --scope @yd-lerna-dev/button -- rm -rf ./node_modules
当然,你也可以去执行其他各种有用的命令,还有就它和 lerna run
有点相似,但两者还是有区别的。
lerna diff
该命令用于对比子包更改前后的差异,和 git diff
是一模一样的作用。
展示所有子包的更改差异:
lerna diff
(按 q
退出)
展示某个子包的更改差异:
lerna diff @yd-lerna-dev/button
(注意,没有 --scope
参数哦)
lerna changed
该命令用于检查自上次发布后,最新提交到远程仓库中的代码,有哪些包发生了变化。
lerna list
该命令用于列出所有子包的信息,可以有几种输出形式。
lerna info
该命令用于打印本地环境信息。
lerna ls
列出所有公开的包,private: true
的除外。
至此,本篇文章就写完啦,撒花撒花。
希望本文对你有所帮助,如有任何疑问,期待你的留言哦。 老样子,点赞+评论=你会了,收藏=你精通了。
转载自:https://juejin.cn/post/7144903788473057310