✨ feat(app1,pkg1): monorepo生成规范化提交信息的最优解 - committier

仓库 (喜欢的话请帮我点个star🌟,感谢)

文档

视频教程

上期介绍文章 https://juejin.cn/post/7581408984415338515

为何诞生

开发这个工具的起因很简单,只是想给commit msg加上漂亮的emoji, 我找遍了社区所有的工具,没有一个能完美实现 DX懒人化 + 任意提交方式(不局限CLI) + 一致性 + 规范化 + 语义化版本控制 的完整闭环。

commitizen(cz), git-cz, cz-git, gitmoji 这类工具都无法做到完美,它要求开发者必须用其提供的CLI工具通过交互式命令行表单来选择emoji 输入提交信息来完成提交,但实际情况是并不能严格要求协作者只能用CLI工具提交,我们希望开发者无论是GUI CLI 还是 git commit -m 'xxx'都能自动加上emoji,甚至是github workflow中由工作流提交也能自动转换成符合规范的提交信息,这是最省心的且严谨的。

commitlint能很好的校验提交信息格式规范,但是它太严谨了,feat:foo 这一段提交就会报错,因为:后面少了空格,✨ feat: foo也会报错,因为它默认不支持emoji

所以基于以上两种搭配陷入困境:

  • 要emoji就必须用交互式CLI表单的提交方式
  • 要emoji就不能上commitlint
  • 表单提交方式就无法兼顾CICD机器人提交规范化

因此诞生了committier, 可以让你任意提交,git hook会捕获你的提交信息,工具背后的解析器和规则集会自动读取monorepo中的变更,帮你转换成符合conventional commits规范的提交信息,既能附带emoji也能完美通过commitlint校验。

复杂性不会凭空消失,只会转移

这不是一个"又多一个"的那种工具,而是明确提交阶段的职责,将多个传统工具用这一个工具取代,并降低心智负担,less is more。将开发者(用户)在大型monorepo中规范化的复杂性转移到工具背后。

7加减2原则

开发者在每个阶段,工具本身不应该带来超过7+-2个需要记忆的知识,超过即是心智负担。

在传统的cz工具中,我们需要记忆提交只能用cli、源码改动了哪几个包填写哪些scope、类型有哪几种、这种类型对应了哪个emoji、输入格式要注意大小写等等,这明显负担太重了,简简单单一个提交为了迎合规范记那么多真的值得吗?

而committier能极大减少你需要额外学习和记忆的知识,90%情况下你只需要知道'feat', 'fix', 'chore'这三个关键词足矣。

  1. git add ... 2. git commit -m feat... 3. 完事

committier 💗 commitlint

committier和commitlint的关系就像prettier和eslint。前者是约定大于配置的,无须任何配置即可按照默认推荐的风格完成自动转换和格式化,附加emoji, scope, 甚至自动生成description(如果你真的很懒),但它不会像lint那样强校验你的输入长度、特殊字符等等,因此这两个工具既可以完美配合,也可以任选其一单独使用,选择权在你。

语义化自动生成changelog

要实现自动生成,首先要确保commit msg是符合语义化(conventional commits)的

由于

  • committier -> 始终将commit msg转化成符合语义化的格式
  • commitlint -> 强校验commit msg确保只有符合语义化的格式

因此无论是组合或者任选其一,都能为后续生成changlog做准备。

这两个工具都没有内置changelog生成,因为日志属于版本控制的环节,不应该将日志提前到commit环节,所以将日志交给版本控制的专用工具。

版本控制主要分为两派工具

  • 语义化:nx、lerna、semantic-release
  • 文档: changesets

我推荐使用nx, 因为它能提取规范化的提交信息作为日志内容自动生成changelog, 免除开发者手写变更文档的麻烦,主打一个能偷懒则偷懒。

nx本身是一个很重的工具,有一定上手成本,但是我们不一定要用它的任务流、缓存等功能,如官方所说建议渐进式使用,只用它的nx release相关功能就可以了,我个人推荐在monorepo中的完美初始组合是:

pnpm workspace + husky + committier + commitlint + nx release

这些已经足够你构建项目、规范提交、版本控制、发布。

committier自动生成scope、description

默认是不会自动生成的,需要在配置文件中开启

committier.config.js

js 复制代码
import { defineConfig } from "committier";

export default defineConfig({
  autoScope: true,
  defaultDescription: true
});

假设现在提交两个文件分别在:

  • apps/webapp/src/app.tsx (包名为@mycomp/webapp)
  • packages/components/src/button.tsx (包名为@mycomp/components)

添加到暂存区

sh 复制代码
git add -A

书写信息并提交,但这里我想偷懒,连信息都懒得写,我们只写一个feat表示这是一个特性变更

sh 复制代码
git commit -m "feat"

自动推断出变更的包名作为scope, 由于description没写,自动填充文件名作为信息

转换后, 提交成功成功✅

sh 复制代码
✨ feat(webapp,components): app.tsx, button.tsx

现在撤销commit, 重新来个不偷懒的书写例子, 但是我格式是很乱的,看看会不会被格式化

sh 复制代码
git commit -m "feAT app,comp :   Add button comp  "

转换后,提交成功✅

sh 复制代码
✨ feat(webapp,components): add button comp

app,comp是不合法的包名,因此被替换成正确的包名,description也从大小改为了小写,中间一堆空格也去掉了

以上使用场景很大程度上降低了monorepo跨包开发提交时手写scope的心智负担,因为往往我们很难记得住这次提交到底改动了哪些包,如果改动比较小,信息都可以不用写,允许开发者选择性偷懒,这对于非特性变更比较方便,例如

  • chore -> chore(webapp): vite.config.ts
  • docs -> docs: up README.md

committier后续规划

  1. 收集用户体验建议,按需增加规则集,例如自动转换issue链接,body转换markdown格式等等,任何idea都可以在评论区或者开发交流群里讨论、pr、协作都可以。
  2. rust重写,主要是为了分发纯二进制执行程序,让其他语言无需依赖node环境也能集成,另外还能提升解析性能 即使可以忽略不计。
  3. 插件化设计,源码比较整洁,架构已分层设计,随时可以插件化,但需要好好设计一下api
  4. 本地轻量模型,真正实现0手写自动生成,这个比较有难度,目前还没看到可行的解决方案,需要观摩、等待,大家有好的点子请一定告诉我🙏,要综合考虑模型大小 纯cpu速度 跨平台性。大模型可以不考虑,api接入普适性不强,主流ai IDE已经可以自动生成可以结合committier按需使用。
  5. Gitub workflow actions,提供一个流水线插件,方便其他语言集成,以及修复pr提交者越过本地校验而提交的不符合格式的信息。
  6. 文档补上简体中文
相关推荐
Zyx20072 小时前
Vue 3 实现 AI 流式输出(上篇):从用户体验说起
javascript
zhougl9962 小时前
前台访问服务的方法
javascript
失败又激情的man2 小时前
爬虫逆向之阿里系cookie acw_sc__v2 逆向分析
前端·javascript·爬虫
小肖爱笑不爱笑2 小时前
Vue Ajax
前端·javascript·vue.js·web
四瓣纸鹤2 小时前
闭包到底是啥?
javascript·闭包
帅次3 小时前
系统分析师:软件需求工程的需求定义、需求验证和需求管理
软件工程·软件构建·需求分析·代码规范·设计规范·规格说明书·代码复审
Moment3 小时前
一文搞懂 Tailwind CSS v4 主题变量映射背后的原理
前端·javascript·面试
我命由我123453 小时前
JavaScript WebGL - WebGL 引入(获取绘图上下文、获取最大支持纹理尺寸)
开发语言·前端·javascript·学习·ecmascript·学习方法·webgl