内容简介:一般开源项目正常的开发流程是:表面看起来没有什么毛病,但是要做一个那在多人协作的开发过程中到底会碰到哪些无法统一的行为?我们该如何解决这些问题?
一般开源项目正常的开发流程是:
- 初始阶段
- 创建仓库
- git clone repository 到本地
- 添加修改代码
- 提交commit message
- push到 github 仓库
- 迭代阶段
- 切换开发分支
- 开发新功能
- 完善测试用例
- 日常修复bug
- 文档的完善
- 发布阶段
- 打tag
- npm publish
表面看起来没有什么毛病,但是要做一个 规范的 、 多人协作的 、 可维护的 开源项目,开发流程上还是有不少细节的点需要我们来打磨。
那在多人协作的开发过程中到底会碰到哪些无法统一的行为?我们该如何解决这些问题?
- 代码检查
- 提交信息和修改日志
- 版本迭代
- 执行落地
代码检查
问题
这是一个老生常谈的问题,语句结尾要不要分号?缩进是空格还是tab?是2个还是4个?
解决步骤
目前业界比较统一的做法是使用 eslint
作为项目owner,建议全局安装 eslint
:
npm install eslint -g 复制代码
之后就可以在本地的项目仓库中,执行命令:
eslint --init 复制代码
可以有三种选择:
常规的前端项目建议选用 Standard
规范(虽然不是真正的规范,但是属于业内默认的规范吧),初始化如下:
{ "devDependencies": { "eslint": "^4.19.1", "eslint-plugin-import": "^2.13.0", "eslint-config-standard": "^11.0.0", "eslint-plugin-standard": "^3.1.0", "eslint-plugin-promise": "^3.8.0", } } 复制代码
React项目建议选用 Airbnb
规范,初始化后的 package.json
如下:
{ "devDependencies": { "eslint": "^4.19.1", "eslint-config-airbnb": "^17.0.0", "eslint-plugin-import": "^2.13.0", "eslint-plugin-react": "^7.10.0", "eslint-plugin-jsx-a11y": "^6.1.1" } } 复制代码
如果需要单独定义一些规则,可以在根目录下新建一个 .eslintrc
文件,见具体配置。
如果需要忽略一些文件,可以在根目录下新建一个 .eslintignore
文件,见具体配置。
最后在 package.json
中加上命令
{ "scripts": { "lint": "eslint --ext .jsx,.js ." } } 复制代码
这样项目成员只需要操作以下步骤
-
vscode
中安装eslint
扩展(以后使用vscode
打开项目都会检测项目中的.eslintrc
文件进行实时lint提示) -
cd project && npm install
衍生问题1
如果是之前的老项目接入了eslint,同时加入了git hook来强制执行,会导致之前的错误没修复完无法提交,那有没有办法只检测当前修改的文件呢?
解决方案
目前社区比较成熟的方案是 lint-staged
首先在项目中安装 lint-staged
和 husky
husky是用来实现绑定git hooks的一个库,后面会提到
npm install -D lint-staged husky 复制代码
然后在项目中的 package.json
中添加
{ "scripts": { "precommit": "lint-staged" }, "lint-staged": { "*.js": ["eslint --fix", "git add"] } } 复制代码
以上操作在我们正常的开发流程中做了什么呢?
在 git add .
之后, git commit
之前,会触发 precommit
钩子,执行 lint-staged
,然后 lint-staged
会只检查经过暂存区的文件,根据它的配置项执行命令。
例如上面的配置,就是针对所有修改过的以 js
为后缀的文件,依次执行 eslint --fix
, git add
两个命令,帮你自动修复掉 eslint
的错误,再将修改添加到暂存区,然后一起 commit
到工作区。
衍生问题2
eslint只是作为代码检测的工具,并没有规范开发时的行为,那可不可以在编辑器上进行规范呢?
解决方案
主流方案是使用EditorConfig
首先在项目根目录新建一个 .editorconfig
文件,根据 EditorConfig支持的大部分属性 自行定义
然后再给编辑器安装 EditorConfig
的插件,就可以使用了,插件安装可见官方下载
提交信息和修改日志
问题
-
commit message
在实际开发的过程中,其实大家对自己的修改内容并没有很好的界定,也没有统一的格式化,导致了很多时候我们无法根据commit message来快速定位修改内容。
-
changelog
其实一个项目新增功能,修复bug等信息都需要记录下来,便于区别不同版本的新特性,然后手动维护记录通常容易忘记,导致这一部分经常没有持续的更新。
解决步骤
目前社区使用最广的方案是 Commitizen 和 conventional-changelog 配合使用。
顾名思义
-
commitizen
就是用来 规范commit message
-
conventional-changelog
可以根据格式化的commit message
来 自动生成CHANGLOG.md
commitizen
有两种开发方式:
-
全局安装( 墙裂推荐 ):
npm install commitizen -g 复制代码
然后安装
commitizen
的adpater
,比如cz-conventional-changelog
(AngularJS的提交惯例)npm install -g cz-conventional-changelog 复制代码
然后你就可以使用
git cz
来替换git commit
命令来进行代码提交了。 -
项目安装:
让你的项目让别人更友好的接入commit规范,你不可能强制要求别人全局安装一个工具,就只能在开发依赖里添加
作为项目owner,默认已经全局安装了
commitizen
,然后执行:commitizen init cz-conventional-changelog --save-dev --save-exact 复制代码
以上命令做了三件事:
-
在本地安装
cz-conventional-changelog
模块 -
保存到
package.json
的devDependencies
中 -
在
package.json
的根层级添加了config.commitizen
"config": { "commitizen": { "path": "cz-conventional-changelog" } } 复制代码
为了保证其他贡献者的仓库中也能使用同一版本的
commitizen
,最好在仓库安装开发依赖npm install -D commitizen 复制代码
然后在项目的
package.json
中的scripts
里加上{ "scripts": { "cz": "git-cz" } } 复制代码
这里需要 注意 一点,如果你在
scripts
脚本中定义了{"commit": "git-cz"}
的话,precommit
钩子会在真正commit之前执行两次,见 husky issue ,所以自定义另外一个名称就好了。然后项目contributors就可以通过
npm run cz
来愉快的提交格式化的commit message了。 -
changelog
还是国际惯例,全局安装
npm install -g conventional-changelog-cli 复制代码
切换到项目目录后,执行
conventional-changelog -p angular -i CHANGELOG.md -s -r 0 复制代码
就可以根据commit message 自动生成一份CHANGELOG.md文件
再配合上 package.json
里的 scripts
{ "scripts": { "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0" } } 复制代码
只需要执行 npm run changelog
就行了,是不是很简单?
但是该在什么时机执行上面这条命令呢?
根据 文档推荐的工作流 ,在修改 package.json
中的版本之后执行最合适。
不过在下面的 版本控制 会将工作流改成用 npm version
来实现。
{ "scripts": { "version": "npm run changelog && git add CHANGELOG.md" } } 复制代码
版本迭代
问题
传统版本迭代步骤
-
package.json
中修改递增version
-
git add -A
-
git commit -m "update version"
-
git push
-
git tag <tag version>
-
git push --tag
-
npm publish
流程过于繁冗,很容易遗漏打tag那一步。
解决步骤
使用 npm version
命令,从文档上我们可以看到其依据semver支持了大部分alias:
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git] 复制代码
例:初始版本为1.0.0
npm version prepatch
//预备补丁版本号 v1.0.1-0
npm version prerelease
//预发布版本号 v1.0.1-1
npm version patch
//补丁版本号 v1.0.2
npm version preminor
//预备次版本号 v1.1.0-0
npm version minor
//次版本号 v1.1.0
npm version premajor
//预备主版本号 v2.0.0-0
npm version major
//主版本号 v2.0.0
当在仓库中执行 npm version时
,会自动提交 git commit
并打上 git tag
。
当使用 -m
参数时,就可以自定义发布版本的信息,其中 %s
可以用来代替当前版本号
npm version patch -m "upgrade to %s for reasons" 复制代码
这样以后版本迭代只需要以下步骤
npm version patch | minor | major | ...etc git push git push --tag npm publish
衍生问题
如何发布beta,rc,alpha版本呢?如果发布了,应该如何安装?
解决方案
首先我们要理解这些版本的含义
- alpha:内部测试版本
- beta: 公开测试版本
- rc: 候选版本(Release Candidate)
然后将 package.json
的 version
改成 x.x.x-beta
配合 npm publish --tag <tag>
,我们可以发布对应的 dist-tag
举个例子:
使用 npm publish --tag beta
发布后,然后就可以使用 npm install <pkg>@beta
安装对应版本的包。
我们可以通过 npm dist-tag ls <pkg>
来查看包的 dist-tag
{ latest: 1.0.1, // 这就是npm publish默认发布的tag beta: 1.0.1-beta } 复制代码
当我们的beta版本稳定后,可以使用 npm dist-tag add x.x.x-beta latest
设置为稳定版本。
执行落地
问题
正常工作流我们分为两块:
-
开发流程
在开发流程中,我们需要 保障 :
- 代码lint通过
- 单元测试通过
- 规范的提交信息(optional)
-
发布流程
在发布流程中,我们需要 保障 :
- 打包通过
- 生成CHANGELOG
- 规范的版本号迭代
解决方案
根据上述两种流程,我们可以使用 git hook
和 npm hook
开发流程
在上面已经介绍过,我们选用 husky 作为 git hook
的实现工具
npm install -D husky 复制代码
代码lint和单元测试,我们可以放到 precommit
中执行,修改钩子执行的命令
{ "scripts": { "test": "jest", "precommit": "lint-staged && npm run test" } } 复制代码
commit message lint的解决方案: commitlint
npm install -D @commitlint/config-conventional @commitlint/cli 复制代码
然后在 package.json
中配置钩子
{ "scripts": { "commitmsg": "commitlint -E GIT_PARAMS" }, "commitlint": { "extends": ["@commitlint/config-conventional"], "rules": { "subject-case": [0] } } } 复制代码
这样我们在 git commit
执行之前验证了 eslint
是否通过,测试用例是否通过, commit message
是否符合规范。
当然也可以在 commit
后面添加参数 --no-verify
来跳过commit message lint
发布流程
-
bump version
修改
package.json
{ "scripts": { "version": "npm run changelog && git add CHANGELOG.md", "postversion": "git push && git push --tags" } } 复制代码
然后执行
npm version patch | minor | major
-
npm publish
添加
prepare hook
{ "scripts": { "prepare": "npm run build" } } 复制代码
然后执行
npm publish
执行 npm version
命令时会依次执行 npm script
中的 preversion
, version
, postversion
三个钩子,具体详情见文档
为什么要使用 prepare
而不用 prepublish
,在npm@4.x之后,建议使用 prepare
,具体详情可见声明
结尾
至此,我们已经基本打造了一个比较完善的开源项目workflow。
对于项目开发者来说,只需要做以下几点改变:
- 编辑器安装
eslint
和editorconifg
插件 - 使用
git cz
提交信息 - 使用
npm version patch | minor | patch
来进行版本迭代
是不是更简单方便了呢?
欢迎大家拍砖,广纳良言!
参考文献
以上所述就是小编给大家介绍的《如何打造规范的开源项目workflow》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 微服务开源项目ServiceComb 毕业成为Apache顶级项目
- Facebook 2018 年度开源回顾:新增开源项目 153 个
- 欧盟向 14 个开源项目提供 Bug 悬赏,多是“老牌”项目
- 开源一个文本分析项目
- 如何学习开源项目
- 开源存储项目知多少
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。