通常开源项目正常的开发流程是:javascript
表面看起来没有什么毛病,可是要作一个规范的、多人协做的、可维护的开源项目,开发流程上仍是有很多细节的点须要咱们来打磨。html
那在多人协做的开发过程当中到底会碰到哪些没法统一的行为?咱们该如何解决这些问题?前端
这是一个老生常谈的问题,语句结尾要不要分号?缩进是空格仍是tab?是2个仍是4个?java
目前业界比较统一的作法是使用eslintreact
做为项目owner,建议全局安装eslint
:git
npm install eslint -g
复制代码
以后就能够在本地的项目仓库中,执行命令:github
eslint --init
复制代码
能够有三种选择:npm
常规的前端项目建议选用Standard
规范(虽然不是真正的规范,可是属于业内默认的规范吧),初始化以下:json
{
"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
以下:promise
{
"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
若是是以前的老项目接入了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
到工做区。
eslint只是做为代码检测的工具,并无规范开发时的行为,那可不能够在编辑器上进行规范呢?
主流方案是使用EditorConfig
首先在项目根目录新建一个.editorconfig
文件,根据EditorConfig支持的大部分属性自行定义
而后再给编辑器安装EditorConfig
的插件,就可使用了,插件安装可见官方下载
commit message
在实际开发的过程当中,其实你们对本身的修改内容并无很好的界定,也没有统一的格式化,致使了不少时候咱们没法根据commit message来快速定位修改内容。
changelog
其实一个项目新增功能,修复bug等信息都须要记录下来,便于区别不一样版本的新特性,而后手动维护记录一般容易忘记,致使这一部分常常没有持续的更新。
目前社区使用最广的方案是Commitizen和conventional-changelog配合使用。
顾名思义
commitizen
就是用来规范commit message
conventional-changelog
能够根据格式化的commit message
来自动生成CHANGLOG.md
有两种开发方式:
全局安装(墙裂推荐):
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了。
仍是国际惯例,全局安装
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版本呢?若是发布了,应该如何安装?
首先咱们要理解这些版本的含义
而后将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
设置为稳定版本。
正常工做流咱们分为两块:
开发流程
在开发流程中,咱们须要保障:
发布流程
在发布流程中,咱们须要保障:
根据上述两种流程,咱们可使用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
添加prepublishOnly hook
{
"scripts": {
"prepublishOnly ": "npm run build"
}
}
复制代码
而后执行npm publish
执行
npm version
命令时会依次执行npm script
中的preversion
,version
,postversion
三个钩子,具体详情见文档
prepublishOnly
只会在npm publish
以前执行,prepare
和prepublish
都会在npm publish
和不带参数的npm install
时执行,见npm script文档
至此,咱们已经基本打造了一个比较完善的开源项目workflow。
对于项目开发者来讲,只须要作如下几点改变:
eslint
和editorconifg
插件git cz
提交信息npm version patch | minor | patch
来进行版本迭代是否是更简单方便了呢?
欢迎你们拍砖,广纳良言!