-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lerna workflow #16
Comments
更新: git tag 操作由 publish 脚本来承担 |
packages 下的 modules 相互依赖可以不使用 |
@oMaten 感谢提醒,后续修正下. |
Lerna最大的优点: Splitting up large codebases into separate independently versioned packages is extremely useful for code sharing. 作者说的优点其实没有lerna也可以实现。 |
@techbirds 感觉你是不是看错了什么,lerna 只是一种项目管理方式下的工具端实现。 |
可能我没表达明白,只是觉得作者的这篇文章没有表达monoRepo的核心作用,你说的优点和缺点都没问题。不过也可能是我没get到你的点。@pigcan |
@techbirds 非常欢迎王同学把自己的观点亮出来。这样我写文章的意义也就大了。 |
@pigcan 我给前辈发了一封邮件(gmail),在lerna工作流中遇到了一些问题,希望有时间可以帮忙看看,回复一下~~thanks~ |
@Mr-jiangzhiguo 不是. 发布后续交给另外的流程来处理 |
不对应啊: 另外,我看官方api,你这里有参数没找到,有的参数都Deprecated了, |
@Mr-jiangzhiguo 那确实有可能 lerna 自身已经发生了很大的变化. 但这套方式我现在在内部工程里面还有在用. lerna 我是固定在某个版本的. |
示例仓库
在讲 lerna workflow 前我们先粗话来谈下当今主流的项目代码管理方式
杂谈项目管理方式
multiRepos
这是最常见的项目管理方式
优点
:缺点
:monoRepo
优点
:缺点
:^
总结
项目开发中使用 multiRepos 和 monoRepo 都可以,问题在于项目合不合适。
个人角度上:
合适的项目需要有以下特征
符合以上条件我个人比较建议采用 monoRepo,以及与之带来的 lerna workflow。
当前使用 lerna确实还会有些小问题,这也是我们需要解决的点。
lerna workflow
先再次简单的介绍下 lerna
lerna 模式
在初始化一个项目之前我们必须要清楚,lerna 对管理 monoRepo 有两种模式
Fixed/Locked 模式
: 官方默认推荐模式,当前 babel 的项目管理模式,在该模式下所有的 packages 都会遵循一个版本号,该版本号维护在lerna.json
的 version 字段中,当需要版本发布时lerna publish
时,如果一个模块和上一次 release 相比有过变更的话,会自动发布一个新版本。这种模式的问题在于:当有一个 major 变更的时候,所有 packages 都会都会有一个新的 major 版本。
Independent 模式
: 在该模式下所有 packages 新版本的生成将会由开发者决定,lerna.json
的 version 字段也会随之失效。这种模式的弊端非常明显,开发者必须要非常清晰该发什么版本,事实上在多人协作项目上很难做到这一点。简单命令速记
初始化一个 lerna 项目
默认给当前所有的 packages 添加一个依赖
这边需要推荐一个比较有用的命令
这种方式是可以快速建立 packages 的依赖关系,而不用人为手动建立
这个命令会安装好所有 packages 的依赖,以及建立好 packages 相互依赖的软连接
正式流程为:
发布一个版本。
正式流程为:
caret (^)
.较为有用的附加参数
--npm-tag
使用传入的 tag 把包发布至 npm 对应的 dist-tag
--conventional-commits
遵从 Conventional Commits Specification 进行版本生成和 changlog 生成。
--skip-git
跳过 git 打标
--skip-npm
跳过 npm 发布
--cd-version
指定发包的时的语义版本
移除所有 package 下的 node_modules 目录.
从现有仓库导入一个 package,这种方式下会保留原有的 commit 的信息
执行 package 下 npm script
在任何 package 下执行任意的命令
getting started
step 1:
step 2:
$ mkdir lerna-example $ cd lerna-example
step 3:
运行完后在 terminal 中执行 tree 后我们可以看到此时的目录结构为
➜ lerna-example git:(master) ✗ tree . ├── lerna.json ├── package.json └── packages
step 4:
运行完后在 terminal 中执行 tree 后我们可以看到此时的目录结构为
➜ lerna-example git:(master) ✗ tree . ├── lerna.json ├── package.json └── packages ├── module-a │ ├── index.js │ └── package.json ├── module-b │ ├── index.js │ └── package.json └── module-base ├── index.js └── package.json
step 5:
如果已知 module-base 被 module-a 和 module-b 共同依赖,同时 module-a 又 依赖 module-b
项目中使用的问题
在协同开发时,假设如果开发人员在 module-base 上发布了一个并不兼容的提交,此时做为 pm 的同学很难在没有提前沟通的情况下获知此次变更,所以在选择版本发布时也很容易出现,因为 lerna 默认对依赖的描述是
^
,所以这在信息不对称的情况下很容易造成线上故障。如何破局呢?
--conventional-commits
,来自动化生成版本以及 changelog关于 commitzen 相关的可以看我另外一篇文章 用工具思路来规范化 git commit message
第二种方案也是目前我们项目中应用最多的。
应用 commitizen 方案后, package.json 变更为
commitizen 应用后仓库结构说明
packages
目录下存放的是所有的子仓库tasks
目录下存放一些全局的任务脚本,当前有用的是publish.js
和changelog.js
changelog.js
,当有发布任务时,请事先执行 npm run changelog,此举意为生成本次版本发布的 changelog,执行脚本时会提醒,本次发布是正式版还是 beta,会予以生成不同版本信息供予发布publish.js
,当 changelog 生成并调整相关内容完毕后,执行npm run publish
,会对如上所有的子 packages 进行版本发布,执行脚本时会提醒,本次发布是正式版还是 beta,会予以不同 npm dist-tag 进行发布日常开发流程
在常规开发中,我们的操作方式会变更为如下:
即当我们需要 commit 时,请使用如下命令
如果你在全局安装过
commitizen
那么,直接在项目目录下执行执行时,会有引导式的方式让你书写 commit 的 message 信息
如果你是 sourceTree 用户,其实也不用担心,你完全可以可视化操作完后,再在命令行里面执行
npm run ct
命令,这一部分确实破坏了整体的体验,当前并没有找到更好的方式来解决。关于为什么需要 commitizen,可以参考 这篇文章
当前我们遵循的是 angular 的 commit 规范。
具体格式为:
type
: 本次 commit 的类型,诸如 bugfix docs style 等scope
: 本次 commit 波及的范围subject
: 简明扼要的阐述下本次 commit 的主旨,在原文中特意强调了几点 1. 使用祈使句,是不是很熟悉又陌生的一个词,来传送门在此 祈使句 2. 首字母不要大写 3. 结尾无需
添加标点body
: 同样使用祈使句,在主体内容中我们需要把本次 commit 详细的描述一下,比如此次变更的动机,如需换行,则使用|
footer
: 描述下与之关联的 issue 或 break change,详见案例这一步,并不需要人为干预,因为
precommit
中的lint-staged
会自动化格式,以保证代码风格尽量一致这一步,同样也不需要人为介入,因为
commitmsg
中的commitlint
会自动校验 msg 的规范使用
在这一步中我们借助了
commitizen
标准化的 commit-msg 以及lerna
中publish
的--conventional-commits
来自动化生成了版本号以及 changelog,但过程中我们忽略了 git tag 以及 npm publish (--skip-git --skip-npm
),原因是我们需要一个时机去修改自动化生成的 changelog。由于第四步中,我们并没有实质意义上做版本发布,而是借以 lerna 的 publish 功能,生成了 changelog,所以后续的 publish 操作被实现在了自定义脚本中,即 publish.js 中。
> 第六步:打 tag给当前分支打好对应的 git tag 信息,推送到开发分支The text was updated successfully, but these errors were encountered: