Source: jsilvax. A Beginner's Guide to Lerna with Yarn Workspaces. Oct/6/2018
当结合在一起时,Lerna和Yarn Workspaces可以简化和优化对多包仓库的管理。 Lerna 通过提供有用的实用命令来处理跨多个包的任务执行,使版本管理和将包发布到NPM Org中成为一种轻松的体验。 Yarn Workspaces 管理我们的依赖关系。它不需要多个node_modules目录,而是智能地优化了依赖关系,将他们一并安装,并允许在一个monorepo中交叉链接依赖关系。Yarn Workspaces提供了像Lerna这样的工具来管理多包仓库。
为了开始,让我们启用Yarn Workspaces吧
yarn config set workspaces-experimental true
现在我们可以通过创建一个模拟项目来说明这些概念了
mkdir my-design-system && cd my-design-system
然后,我们初始化项目
yarn init
并将Lerna添加为开发依赖。
yarn add lerna --dev
然后你会想要初始化Lerna,这将创建一个lerna.json和一个包目录
lerna init
为了设置Lerna开启Yarn工作空间,我们需要配置lerna.json。 让我们添加yarn作为我们的npm客户端,并指定我们使用yarn工作空间。在本教程中,我们将独立地版本化我们的包。
// lerna.json
{
"packages": ["packages/*"],
"version": "independent",
"npmClient": "yarn",
"useWorkspaces": true
}
此时我们应该只有一个根 package.json。在这个根 package.json中,我们需要添加workspaces和private为true。将private设置为true将阻止根项目被发布到NPM。
// package.json
{
"name": "my-design-system",
"private": true,
"workspaces": [
"packages/*"
]
}
创建一个新包的流程
需要在包目录下创建新的包。让我们创建一个模拟表单包
cd packages
一旦我们进入了正确的目录,我们就可以创建并cd到我们的新包中了
mkdir my-design-system-form && cd my-design-system-form
然后我们通过运行 yarn init 来创建一个新的package.json
yarn init
新包的名称应该遵循我们的NPM Org scope命名方式,例如:@my-scope-name。 同样重要的是,新的包要从0.0.0这样的版本开始,因为一旦我们使用Lerna进行第一次发布,它就会发布成0.1.0或1.0.0。
// package.json
{
"name": "@my-scope-name/my-design-system-form",
"version" : "0.0.0",
"main" : "index.js"
}
如果您有一个支持私有包的NPM Org账户,您可以在您的模块的独立包.json中添加以下内容。
"publishConfig": {
"access": "restricted"
}
将本地的兄弟依赖关系添加到特定的包中
现在我们知道了创建新包的流程,假设说我们最后的结构是这样的。
my-design-system/
packages/
my-design-system-core/
my-design-system-form/
my-design-system-button/
如果我们想把my-design-system-button作为依赖关系添加到my-design-system-form中,并让Lerna将它们进行符号链接,我们可以通过cd到该包中来实现。
cd my-design-system-form
然后运行以下内容。
lerna add @my-scope-name/design-system-button --scope=@my-scope-name/my-design-system-form
这将更新@my-scope-name/my-design-system-form的package.json。 我们的package.json应该是这样的。
// package.json
{
"name": "@my-scope-name/my-design-system-form",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"@my-scope-name/my-design-system-button": "^1.0.0"
}
}
现在,你可以在index.js中引用这个本地依赖关系,如
import Button from '@my-scope-name/my-design-system-button';
为所有的包添加一个 "共同 "的依赖关系
做法和前面的命令类似。不过这是针对/packages/* 的。不管你要加的依赖是本地的同级依赖还是来自NPM的依赖,都没关系。
lerna add the-dep-name
如果你有常见的开发依赖,最好在 workspace 的 root package.json中指定。例如,可以是Jest、Husky、Storybook、Eslint、Prettier等依赖项
yarn add husky --dev -W
*添加-W标志,就可以明确表示我们要把依赖关系添加到工作区根目录。
删除依赖
如果有一个所有包都使用的依赖,但你想删除,Lerna有exec命令,可以在每个包中运行一个任意命令。有了这些知识,我们就可以使用exec来删除所有包的依赖关系。
lerna exec -- yarn remove dep-name
运行测试
Lerna提供了run命令,它将在每个包含了npm脚本的包中运行该脚本。 例如,假设我们所有的包都遵循my-design-system-form的结构。
my-design-system-form/
__tests__/
Form.test.js
在每个package.json中,我们都有测试的npm脚本。
"name": "@my-scope-name/my-design-system-form",
"scripts": {
"test": "jest"
}
然后Lerna可以通过运行每个测试脚本来执行。
lerna run test --stream
*-stream 这个flag提供子进程的输出。
发布到NPM
手动
首先,你需要确保你已经登录了。你可以通过以下操作来验证你是否已经登录。
npm whoami // myusername
如果你没有登录,请运行以下内容并按照提示操作。
npm login
登录后,您可以通过运行Lerna发布。
lerna publish
Lerna会提示你更新版本号。
自动
Lerna支持使用Conventional Commits Standard在CI环境中自动进行语义版本管理。 这使开发人员能够像下面这样提交
git commit -m "fix: JIRA-1234 Fixed minor bug in foo"
然后在CI环境中,包的版本可以根据上面的提交更新并发布到NPM。这可以通过配置你的CI环境来完成。
lerna publish --conventional-commits --yes
如果你不想传递flag,可以在你的lerna.json文件中添加以下内容。
"command": {
"publish": {
"conventionalCommits": true,
"yes": true
}
}
强制执行 Conventional Commits
如果你想强制执行 Conventional Commits 标准,我建议在项目的ROOT中加入Commitlint。
yarn add @commitlint/cli @commitlint/config-conventional husky cross-env --dev
然后在根package.json中创建一个发布脚本
"scripts": {
"release": "cross-env HUSKY_BYPASS=true lerna publish"
}
这个发布脚本将在CI环境中运行。请注意,我们在 lerna.json 文件中配置了传统的提交和 "yes "标志。由于这个CI环境将会把版本的变更提交,我们不希望触发提交消息的inting。我们通过添加一个名为HUSKY_BYPASS的环境变量来实现,我们将使用cross-env将其设置为true。 我们还需要在root package.json中添加进一步的配置。
"husky": {
"hooks": {
"commit-msg": "[[ -n $HUSKY_BYPASS ]] || commitlint -E HUSKY_GIT_PARAMS"
}
},
"commitlint": {
"extends": ["@commitlint/config-conventional"]
}
对于husky,我们添加了一个commitlint/config-conventional的commit-msg钩子,它将检查我们在上面添加的HUSKY_BYPASS环境变量,如果这个变量是假的,那么我们通过@commitlint/config-conventional来精简提交消息。
分离版本控制与发布
如果出于任何原因,你想完全掌控版本控制,Lerna有能力将版本控制和发布分成两个命令。 你可以手动运行。
lerna version
然后按照提示更新各个版本号。 然后你就可以有一个步骤,读取最新的标签(是手动更新的)发布到NPM。
lerna publish from-git --yes
多贡献者参与的本地开发
每当有新的贡献者对你的项目进行git克隆,或者你需要拉取你团队的最新变化时,你必须运行yarn命令。
yarn
在大多数的Lerna教程中,提倡使用lerna bootstrap命令,然而当启用yarn工作空间时,这是不必要的,也是多余的
lerna bootstrap when you're using Yarn workspaces is literally redundant? All lerna bootstrap --npm-client yarn --use-workspaces (CLI equivalent of your lerna.json config) does is call yarn install in the root. — Issue 1308
更多信息见https://github.com/lerna/lerna/issues/1308
跨项目的本地开发
在我们的例子中,我们正在构建一个多包设计系统。如果开发人员想在设计系统中创建一个新的组件,但在发布之前也要在本地客户端应用程序中进行测试,他们可以通过使用yarn的链接命令来实现。
建立本地依赖关系的symlink
假设我们想在my-client-app中使用我们本地的my-design-system-core。 我们先cd到我们要在另一个项目中用到的软件包。
cd ~/path/to/my-design-system/my-design-system-core
然后我们创建一个symlink
yarn link
你应该看到这样的输出
success Registered "@my-scope-name/my-design-system-core".
info You can now run `yarn link "@my-scope/my-design-system-core"` in the projects where you want to use this module and it will be used instead.
现在我们的包已经有了符号链接,我们可以进入my-client-app中使用。
cd ~/path/to/my-client-app
yarn link @my-scope-name/my-design-system-core
在 /packages/my-design-system-core 中的任何变化都会反映在my-client-app中。现在,开发人员可以很容易地在两个项目上进行本地开发,并看到它的反映。
解除本地依赖关系的链接
当开发者完成后,不再想使用本地的包时,我们需要解除链接。 cd到入我们要解除链接的包中
cd ~/path/to/my-design-system/my-design-system-core
运行unlink删除本地symlink
yarn unlink
你会看到这样的输出
success Unregistered "@my-scope-name/my-design-system-core".
info You can now run `yarn unlink "@my-scope-name/my-design-system-core"` in the projects where you no longer want to use this module.
现在,我们可以cd到my-client-app中解除链接。
cd ~/path/to/my-client-app
yarn unlink @my-scope-name/my-design-system-core
总结
Lerna与Yarn Workspaces是一个很好的组合。Lerna 在 Yarn Workspaces 的基础上增加了实用功能,用于处理多个包。纱线工作空间使得所有的依赖关系可以一起安装,使得缓存和安装速度更快。它让我们可以通过一个命令轻松地在NPM上发布依赖关系,当依赖关系的版本发生变化时,自动更新兄弟依赖关系的package.json,一般来说,安装、版本管理和发布都是一种无痛的体验。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!