lerna
概要
lerna是GitHub上面開源的一款js代碼庫管理軟件, 用來對(duì)一系列相互耦合比較大、又相互獨(dú)立的js git庫進(jìn)行管理揖闸。解決各個(gè)庫之間修改混亂揍堕、難以跟蹤的問題。lerna可以優(yōu)化這種情形下的工作流汤纸。
對(duì)于一些功能比較全的庫衩茸,我們往往會(huì)把各個(gè)小功能拆分成獨(dú)立的npm庫,他們直接有比較強(qiáng)的依賴關(guān)系贮泞。比如:Babel楞慈、React等開源代碼都是按照這種方式進(jìn)行處理的。
代碼庫結(jié)構(gòu)
lerna管理的庫文件結(jié)構(gòu)類似如下這樣
my-lerna-repo/
package.json
packages/
package-1/
package.json
package-2/
package.json
lerna主要做了什么
- 通過lerna的命令
lerna bootstrap
將會(huì)把代碼庫進(jìn)行l(wèi)ink啃擦。 - 通過
lerna publish
發(fā)布最新改動(dòng)的庫
Get Started
下面使用3.x版本的lerna進(jìn)行測(cè)試囊蓝, 官方也建議使用3.x代替2.x
首先,初始化lerna庫
cd lerna-repo
lerna init
默認(rèn)會(huì)創(chuàng)建lerna.json和packages目錄, 如下
lerna-repo/
packages/
package.json
lerna.json
lerna如何工作的
默認(rèn)lerna有兩種管理模式令蛉, 固定模式和獨(dú)立模式
固定模式
固定模式聚霜,通過lerna.json的版本進(jìn)行版本管理。當(dāng)你執(zhí)行lerna publish
命令時(shí)珠叔, 如果距離上次發(fā)布只修改了一個(gè)模塊蝎宇,將會(huì)更新對(duì)應(yīng)模塊的版本到新的版本號(hào),然后你可以只發(fā)布修改的庫祷安。
這種模式也是Babel使用的方式姥芥。如果你希望所有的版本一起變更, 可以更新minor版本號(hào)辆憔,這樣會(huì)導(dǎo)致所有的模塊都更新版本撇眯。
獨(dú)立模式
獨(dú)立模式,init的時(shí)候需要設(shè)置選項(xiàng) --independent
. 獨(dú)立模式允許管理者對(duì)每個(gè)庫單獨(dú)改變版本號(hào)虱咧,每次發(fā)布的時(shí)候熊榛,你需要為每個(gè)改動(dòng)的庫指定版本號(hào)。這種情況下腕巡, lerna.json
的版本號(hào)不會(huì)變化了玄坦, 默認(rèn)為independent
。
lerna.json解析
{
"version": "1.1.3",
"npmClient": "npm",
"command": {
"publish": {
"ignoreChanges": [
"ignored-file",
"*.md"
]
},
"bootstrap": {
"ignore": "component-*",
"npmClientArgs": ["--no-package-lock"]
}
},
"packages": ["packages/*"]
}
- version , 當(dāng)前庫的版本
- npmClient , 允許指定命令使用的client绘沉, 默認(rèn)是 npm煎楣, 可以設(shè)置成 yarn
- command.publish.ignoreChanges , 可以指定那些目錄或者文件的變更不會(huì)被publish
- command.bootstrap.ignore 车伞, 指定不受 bootstrap 命令影響的包
- command.bootstrap.npmClientArgs 择懂, 指定默認(rèn)傳給 lerna bootstrap 命令的參數(shù)
- command.bootstrap.scope , 指定那些包會(huì)受 lerna bootstrap 命令影響
- packages 另玖, 指定包所在的目錄
命令行
lerna publish
發(fā)布新的庫版本
lerna publish // 發(fā)布最新commit的修改
lerna publish <commit-id> // 發(fā)布指定commit-id的代碼
Options
canary
可以用來獨(dú)立發(fā)布每個(gè)commit困曙,不打tag
lerna publish --canary
# 1.0.0 => 1.0.1-alpha.0+${SHA} of packages changed since the previous commit
# a subsequent canary publish will yield 1.0.1-alpha.1+${SHA}, etc
lerna publish --canary --preid beta
# 1.0.0 => 1.0.1-beta.0+${SHA}
# The following are equivalent:
lerna publish --canary minor
lerna publish --canary preminor
# 1.0.0 => 1.1.0-alpha.0+${SHA}
--npm-client
默認(rèn)npm
--npm-tag
為發(fā)布的版本添加 dist-tag
--no-verify-access
不進(jìn)行用戶發(fā)布的權(quán)限校驗(yàn)
--registry <url>
指定registry
--yes
用于ci自動(dòng)輸入 yes
--temp-tag
沒啥用
lerna version
這個(gè)命令 識(shí)別出修改的包 --> 創(chuàng)建新的版本號(hào) --> 修改package.json --> 提交修改 打上版本的tag --> 推送到git上表伦。
版本號(hào) 遵循 semver
Options
--allow-branch <glob>
設(shè)置git上的哪些分支允許執(zhí)行 lerna version 命令, 也可以在lerna.json中設(shè)置
{
"command": {
"publish": {
"allowBranch": "master"
}
}
}
多個(gè)
{
"command": {
"publish": {
"allowBranch": ["master", "feature/*"]
}
}
}
--amend
把version的修改都合并到前一個(gè)commit慷丽, 而且不會(huì)推送哦蹦哼。
--commit-hooks
執(zhí)行對(duì)應(yīng)的commit-hook, 默認(rèn)true
--conventional-commits
使用了這個(gè)選項(xiàng)要糊, lerna會(huì)收集日志纲熏, 自動(dòng)生成 CHANGELOG
--changelog-preset
修改changelog生成插件, 默認(rèn)是 angular
--exact
??? 沒試出什么效果
--force-publish
強(qiáng)制更改所有包的版本锄俄, 不管有沒有修改
--ignore-changes
忽略檢查某些文件的修改
lerna version --ignore-changes '**/*.md' '**/__tests__/**'
也可以在lerna.json中配置
{
"ignoreChanges": [
"**/__fixtures__/**",
"**/__tests__/**",
"**/*.md"
]
}
--git-remote <name>
把修改推送到其它的源局劲, 而不是origin
--git-tag-version
添加git的tag, 默認(rèn)true
--message <msg>
指定提交信息奶赠, 而不是自動(dòng)生成的log
也可以在lerna.json配置
{
"command": {
"publish": {
"message": "chore(release): publish %s"
}
}
}
lerna bootstrap
bootstrap作了如下工作
- 為每個(gè)包安裝依賴
- 鏈接相互依賴的庫到具體的目錄
- 執(zhí)行 npm run prepublish
- 執(zhí)行 npm run prepare
可以通過 -- 后添加選項(xiàng), 設(shè)置npm cient的參數(shù)
lerna bootstrap -- --production --no-optional
也可以在lerna.json中配置
{
...
"npmClient": "yarn",
"npmClientArgs": ["--production", "--no-optional"]
}
Options
--hoist
這個(gè)選項(xiàng)容握,會(huì)把共同依賴的庫安裝到根目錄的node_modules下, 統(tǒng)一版本
--ignore
忽略部分目錄车柠, 不進(jìn)行安裝依賴
lerna bootstrap --ignore component-*
也可以在lerna.json中配置
{
"version": "0.0.0",
"command": {
"bootstrap": {
"ignore": "component-*"
}
}
}
--ignore-scripts
不執(zhí)行聲明周期腳本命令, 比如 prepare
--registry <url>
指定registry
--npm-client
指定安裝用的npm client
lerna bootstrap --npm-client=yarn
也可以在lerna.json中配置
{
...
"npmClient": "yarn"
}
--use-workspace
使用yarn workspace塑猖, 沒用過
--no-ci
默認(rèn)調(diào)用 npm ci 替換 npm install , 使用選項(xiàng)修改設(shè)置
lerna list
列舉當(dāng)前l(fā)erna 庫包含的包
Options
--json
顯示信息為json格式
--all
顯示包含private的包
--parseable
顯示如下格式 <fullpath>:<name>:<version>[:flags..]
--long
顯示更多的擴(kuò)展信息
lerna changed
顯示自上次relase tag以來有修改的包竹祷, 選項(xiàng)通 list
lerna diff
顯示自上次relase tag以來有修改的包的差異, 執(zhí)行 git diff
lerna exec
在每個(gè)包目錄下執(zhí)行任意命令
使用示例
$ lerna exec -- <command> [..args] # runs the command in all packages
$ lerna exec -- rm -rf ./node_modules
$ lerna exec -- protractor conf.js
$ lerna exec -- npm view \$LERNA_PACKAGE_NAME
$ lerna exec -- node \$LERNA_ROOT_PATH/scripts/some-script.js
Options
--concurrency
默認(rèn)命令時(shí)并行執(zhí)行的羊苟, 我們可以設(shè)置并發(fā)量為1
lerna exec --concurrency 1 -- ls -la
--scope
lerna exec --scope my-component -- ls -la
--stream
交叉并行輸出結(jié)果
lerna exec --stream -- babel src -d lib
--parallel
--no-bail
默認(rèn)lerna exec塑陵,如果有命令返回了非0, 則會(huì)停止執(zhí)行蜡励, 通過設(shè)置這個(gè)參數(shù) 忽略返回非0令花, 繼續(xù)執(zhí)行其它命令
lerna run
執(zhí)行每個(gè)包package.json中的腳本命令
$ lerna run <script> -- [..args] # runs npm run my-script in all packages that have it
$ lerna run test
$ lerna run build
# watch all packages and transpile on change, streaming prefixed output
$ lerna run --parallel watch
選項(xiàng)通 lerna exec
lerna init
創(chuàng)建一個(gè)新的lerna庫或者是更新lerna版本
- 修改package.json中l(wèi)erna版本
- 創(chuàng)建lerna.json
Options
--independent
獨(dú)立模式
--exeact
版本號(hào)固定?
lerna add
添加一個(gè)包的版本為各個(gè)包的依賴
$ lerna add <package>[@version] [--dev] [--exact]
lerna clean
刪除各個(gè)包下的node_modules
lerna import
導(dǎo)入指定git倉庫的包作為lerna管理的包
lerna import <path-to-external-repository>
Options
--flatten
如果有merge沖突凉倚, 用戶可以使用這個(gè)選項(xiàng)所謂單獨(dú)的commit
$ lerna import ~/Product --flatten
--dest
可以指定導(dǎo)入的目錄(lerna.json中設(shè)定的目錄)
$ lerna import ~/Product --dest=utilities
lerna link
鏈接互相引用的庫
lerna create
新建包
lerna create <name> [loc]
Create a new lerna-managed package
Positionals:
name The package name (including scope), which must be locally unique _and_
publicly available [string] [required]
loc A custom package location, defaulting to the first configured package
location [string]
Command Options:
--access When using a scope, set publishConfig.access value
[choices: "public", "restricted"] [default: public]
--bin Package has an executable. Customize with --bin
<executableName> [default: <name>]
--description Package description [string]
--dependencies A list of package dependencies [array]
--es-module Initialize a transpiled ES Module
--homepage The package homepage, defaulting to a subpath of the root
pkg.homepage [string]
--keywords A list of package keywords [array]
--license The desired package license (SPDX identifier) [default: ISC]
--private Make the new package private, never published
--registry Configure the package's publishConfig.registry [string]
--tag Configure the package's publishConfig.tag [string]
--yes Skip all prompts, accepting default values