「 用于 管理 拥有多个packages 的 js项目 的工具 」
比如
npm install -g @vue/cli
==> 这样的@vue
样式, 供给 vuejs组织 管理 cli生态链工具 或众多插件,比如gatsbyjs
翻译的原文 | 与日期 | 最新更新 | 更多 |
---|---|---|---|
commit | ⏰ 2018 8.18 | 中文翻译 |
欢迎 👏 勘误/校对/更新贡献 😊 具体贡献请看
If help, buy me coffee —— 营养跟不上了,给我来瓶营养快线吧! 💰
用于 管理 拥有多个packages 的 js项目 的工具.
- 命令
大型的代码库 拆分为 独立的版本包 对 代码共享非常有用,然而,要对这么 多的存储库进行更改是如此凌乱且难以追踪,还有还有 跨存储库测试 也变得非常复杂。
为了解决这样 (那样) 的问题, 一些项目组会将他们的基础代码库分组成多个包库中 (有时称为monorepos) . 项目如babel,react,angular,ember,meteor,jest,和 其他项目组开发他们的包都是在一个repo库.
Lerna是一个优化了git和npm管理多包存储库的工作流程的工具.
Lerna还可以减少开发和构建环境中大量软件包副本的时间和空间的大小 - 通常是将项目划分为多个单独的NPM软件包的缺点. 见
- 提升文件详情.
实际上它真的很小小. 您有一个如下所示的文件系统:
my-lerna-repo/
package.json
packages/
package-1/
package.json
package-2/
package.json
Lerna的两个主要命令是lerna bootstrap
和lerna publish
.
bootstrap
将把repo中的依赖关系链接在一起.publish
将帮助发布任何更新的包.
以下说明适用于Lerna 3.x.对于新的Lerna项目,我们建议使用它而不是2.x版本.
让我们首先安装Lerna作为项目的dev依赖项, 通过npm.
$ mkdir lerna-repo && cd $_
$ npx lerna init
这将创建一个lerna.json
配置文件以及packages
文件夹,所以你的文件夹,现在应该是这样的:
lerna-repo/
packages/
package.json
lerna.json
Lerna允许您使用以下两种模式之一来管理项目: 固定或独立.
固定模式的Lerna项目在单一的版本线上运行. 版本保存在位于项目的根目录下lerna.json
文件的version
字段. 当你运行lerna publish
,自上次发布版本以来,如果模块已更新,它将更新为您要发布的新版本. 这意味着您需要发布包的新版本, 就可以publish
.
这是babel目前正在使用的模式. 如果要自动将所有包的版本绑定在一起,请使用此选项. 这种方法的一个问题是任何包中的重大更改,都将导致所有包更新为新的主要版本.
独立模式的Lerna项目允许维护人员相互独立地增加包版本. 每次发布时,您都会收到每个已更改的包的提示,以指定它是patch,minor,major还是自定义更改.
独立模式允许您更具体地更新每个包的版本,并赋予一组组件意义. 将此模式与类似semantic-release结合起来会减少痛苦. (目前已有Atlassian/lerna-semantic-release在工作) .
在独立模式下
lerna.json
的version
字段被忽略.
- 如果您在使用Lerna时遇到任何问题,请查看我们的故障排除文档,上面记录您可能找到的问题答案.
Lerna将记录lerna-debug.log
文件 (像npm-debug.log
) ,当遇到运行命令的错误时.
Lerna也有支持scoped 包.
运行lerna
没有参数,将显示所有命令/选项.
{
"version": "1.1.3",
"command": {
"publish": {
"ignoreChanges": [
"ignored-file",
"*.md"
]
},
"bootstrap": {
"ignore": "component-*",
"npmClientArgs": ["--no-package-lock"]
}
},
"packages": ["packages/*"]
}
version
: 存储库的当前版本.command.publish.ignoreChanges
: 一组匹配模式,将不包括在lerna changed/publish
内. 使用此选项可防止不必要地发布新版本,例如进行更改修复README.md
错字.command.bootstrap.ignore
: 一组匹配模式,在运行lerna bootstrap
命令时不会被引导.command.bootstrap.npmClientArgs
: 字符串数组,直接传递给npm install
,作为参数. 在lerna bootstrap
命令期间.command.bootstrap.scope
: 一组匹配模式,限制运行时引导哪些包,在lerna bootstrap
命令期间.packages
: 用作包位置的匹配模式数组.
lerna.json
的包配置,匹配包含package.json
的目录列表,这正是lerna
识别它的"leaf"-枝叶包的方法. (vs "根"的package.json,用于管理整个repo的dev依赖项和脚本) .
默认情况下,lerna将包列表初始化为["packages/*"]
,但你也可以使用另一个目录,如["modules/*"]
, 要么["package1", "package2"]
. 定义的模式是相对于lerna.json
所在的目录,通常是存储库根目录. 唯一的限制是您不能直接嵌套包位置,但这也是与"普通"npm包共享的限制一样.
例如,["packages/*", "src/**"]
匹配这棵树:
packages/
├── foo-pkg
│ └── package.json
├── bar-pkg
│ └── package.json
├── baz-pkg
│ └── package.json
└── qux-pkg
└── package.json
src/
├── admin
│ ├── my-app
│ │ └── package.json
│ ├── stuff
│ │ └── package.json
│ └── things
│ └── package.json
├── profile
│ └── more-things
│ └── package.json
├── property
│ ├── more-stuff
│ │ └── package.json
│ └── other-things
│ └── package.json
└── upload
└── other-stuff
└── package.json
叶包在packages/*
的下面,被认为是"最佳实践",但Lerna
不要求一定如此使用.
大多数devDependencies
可以拉到Lerna包的根目录.
这有一些好处:
- 所有包都使用给定依赖项的相同版本
- 使用自动化工具可以使根目录的依赖关系保持最新状态GreenKeeper
- 依赖安装时间减少
- 需要更少的存储空间
注意:devDependencies
提供给 npm scripts 使用的"二进制"可执行文件,仍然需要直接安装在每个使用它们的包中.
比如说nsp
在lerna run nsp
情况下,依赖是必要的 (和npm run nsp
在包的目录内) 才能正常工作:
{
"scripts": {
"nsp": "nsp"
},
"devDependencies": {
"nsp": "^2.3.3"
}
}
Lerna允许将 本地依赖包的目标版本 编写为git remote url,与committish
(例如. ,#v1.0.0
要么#semver:^1.0.0
) ,而不是正常的数字版本范围. 这允许私有包的分发,通过 git存储库,而私人npm注册表是不可取的.
请注意lerna并不执行,将git历史记录实际拆分到单独的只读存储库中. 这是用户的责任. (看到这个评论的实现细节)
// packages/pkg-1/package.json
{
name: "pkg-1",
version: "1.0.0",
dependencies: {
"pkg-2": "github:example-user/pkg-2#v1.0.0"
}
}
// packages/pkg-2/package.json
{
name: "pkg-2",
version: "1.0.0"
}
在上面的例子中,
lerna bootstrap
将正确的符号链接pkg-2
链接到pkg-1
.lerna publish
将更新pkg-1
的委托 (#v1.0.0
) ,当pkg-2
变化时.
[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lernajs.io/)
如果您更想要cli
的一些指导 (如果您即将开始使用lerna或将其介绍给新团队) ,您可能会喜欢lerna-wizard. 它将引导您完成一系列明确定义的步骤: