前言

一般开源项目正常的开发流程是:

  • 初始阶段

    • 创建仓库
    • git clone repository 到本地
    • 添加修改代码
    • 提交commit message
    • push到 github 仓库
  • 迭代阶段
    • 切换开发分支
    • 开发新功能
    • 完善测试用例
    • 日常修复bug
    • 文档的完善
  • 发布阶段
    • 打tag
    • npm publish

表面看起来没有什么毛病,但是要做一个规范的多人协作的可维护的开源项目,开发流程上还是有不少细节的点需要我们来打磨。

那在多人协作的开发过程中到底会碰到哪些无法统一的行为?我们该如何解决这些问题?

  • 代码检查
  • 提交信息和修改日志
  • 版本迭代
  • 执行落地

代码检查

问题

这是一个老生常谈的问题,语句结尾要不要分号?缩进是空格还是tab?是2个还是4个?

解决步骤

目前业界比较统一的做法是使用eslint

作为项目owner,建议全局安装eslint

npm install eslint -g
复制代码

之后就可以在本地的项目仓库中,执行命令:

eslint --init
复制代码

可以有三种选择:

  • 选择一个流行的样式规范

    • Airbnb
    • Standard
    • Google
  • 自定义的代码习惯
  • 检查你项目之前的代码样式

常规的前端项目建议选用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-stagedhusky

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
    复制代码

    然后安装commitizenadpater,比如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.jsondevDependencies

    • 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.jsonversion改成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默认发布的tagbeta: 1.0.1-beta
}
复制代码

当我们的beta版本稳定后,可以使用npm dist-tag add x.x.x-beta latest设置为稳定版本。

执行落地

问题

正常工作流我们分为两块:

  • 开发流程

    在开发流程中,我们需要保障

    • 代码lint通过
    • 单元测试通过
    • 规范的提交信息(optional)
  • 发布流程

    在发布流程中,我们需要保障

    • 打包通过
    • 生成CHANGELOG
    • 规范的版本号迭代

解决方案

根据上述两种流程,我们可以使用git hooknpm 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中的preversionversionpostversion三个钩子,具体详情见文档

prepublishOnly只会在npm publish之前执行,prepareprepublish都会在npm publish和不带参数的npm install时执行,见npm script文档

结尾

至此,我们已经基本打造了一个比较完善的开源项目workflow。

对于项目开发者来说,只需要做以下几点改变:

  • 编辑器安装eslinteditorconifg插件
  • 使用git cz提交信息
  • 使用npm version patch | minor | patch来进行版本迭代

是不是更简单方便了呢?

欢迎大家拍砖,广纳良言!

参考文献

  • eslint中文官网
  • Commitizen
  • conventional-changelog
  • Commit message 和 Change log 编写指南
  • npm version
  • npm publish
  • npm dist-tag
  • husky
  • commitlint
  • npm scripts 使用指南

转载于:https://juejin.im/post/5b624d42f265da0fa1223ffa

如何打造规范的开源项目workflow相关推荐

  1. 适合嵌入式的C++开源项目-Workflow

    在来腾讯之前,我是没有真正用C++开发过一个完整的项目的,然后,赶鸭子上架,鹅厂的人特别喜欢用C++,而且用的特别好.我这次推荐一个开源的C++项目,希望喜欢C++,或者想往C++方向发展的同学可以看 ...

  2. 搜狗开源项目workflow 综述

    2021SC@SDUSC 项目分工 我负责了解workflow如何实现服务寻址,远程过程调用中包含三个角色的节点分别是服务调用方.服务提供方.注册中心,可靠的服务寻址方式主要是为了提供服务的发现,是R ...

  3. usb耳机android,USB 耳机:配件规范  |  Android 开源项目  |  Android Open Source Project...

    本文档详细说明了 USB 耳机的一些特性,以使其在整个 Android 生态系统中保持一致.只允许制造带数字 USB 音频接口的耳机.根据 USB-C 型规范,不允许制造带 USB-C 型转接头的纯模 ...

  4. 打造一个高逼格的android开源项目——小白攻略

    小引子 在平时的开发过程中,我们经常会查阅很多的资料,最常参考的是 github 的开源项目.通常在项目的主页面能看到项目的简介和基本使用,并且时不时能看到页面汇中有好多的彩色标签,看起来很酷,很专业 ...

  5. fir.im Weekly - 如何打造 Github 「爆款」开源项目

    最近 Android 转用 Swift 的传闻甚嚣尘上,Swift 的 Github 主页上已经有了一次 merge>>「Port to Android」,让我们对 Swift 的想象又多 ...

  6. 开源项目推荐:C++ Web/Http Server/Rest开发框架(请重点关注Oat++和搜狗workflow)

    先看参考文献 C++ Web Framework/C++ Web开发框架 - QTCN开发网 - Powered by phpwind 找了一些C++的Web开发框架,看样子不少,有许多是基于Qt的, ...

  7. 微人事 star 数超 10k 啦!聊聊如何打造一个 star 数超 10k 的开源项目

    看了下,微人事(https://github.com/lenve/vhr)项目 star 数超 10k 啦,松哥第一个 star 数过万的开源项目就这样诞生了. 两年前差不多就是现在这个时候,松哥所在 ...

  8. 微人事 star 数超 10k,如何打造一个 star 数超 10k 的开源项目

    看了下,微人事(https://github.com/lenve/vhr)项目 star 数超 10k 啦,松哥第一个 star 数过万的开源项目就这样诞生了. 两年前差不多就是现在这个时候,松哥所在 ...

  9. 如何在Github打造你的爆款开源项目

    目前为止我已经有五个流行项目(登上 Github 的 Trending 页),所以想分享我的一些经验和方法. 如果你开源过代码,就会知道让别人对你的感兴趣是多么困难.这很奇怪,不是吗? 我们花了至少数 ...

最新文章

  1. 云原生生态周报 Vol. 16 | CNCF 归档 rkt,容器运行时“上古”之战老兵凋零
  2. java进阶之路学习笔记
  3. 首航节能:光热行业刚起步 子公司处于亏损状态
  4. Android Monkey压力测试
  5. 【One by One系列】IdentityServer4(二)使用Client Credentials保护API资源
  6. AgileEAS.NET平台开发Step By Step系列-药店系统-索引
  7. flex的三个属性grow、shrink、basis
  8. 最新资源《机器学习图像算法与建模优化》免费开放下载!(含代码数据)
  9. 0点睡觉很会养生”苏宁高管的这话让IT人很憋屈
  10. JDK 1.8 新特性学习(Stream)
  11. 配置grafana的数据源、添加监控
  12. java public就是可选吗_java 中的public
  13. 提升机器学习数学基础,这7本书一定要读-附pdf资源
  14. 一个企图用代码偷懒计算测量学闭合导线各项数据的屑是否有错
  15. 【解决方案】SkeyeVSS石油油田钻井无线智能视频监控系统解决方案
  16. 基于ELK 7.50搭建elastalert 监控报警和权限控制
  17. 如何有效去除博客上的广告
  18. 推荐一款轻量级的支持Markdown的团队知识分享开源软件
  19. 曾因“贿赂”苹果被罚款 10.3 亿美元,高通上诉成功
  20. Java项目:SSM二手汽车交易商城网站管理系统

热门文章

  1. Move to Another Changelist
  2. Erlang error?
  3. Exchange OWA管理-----HTTPS实现OWA表单
  4. Cardinality 对执行计划的重要性
  5. mvc mvp mvvm
  6. JAVA SE学习day_06:字符流、异常处理
  7. Kali Linux缺少ifconfig命令
  8. GRDB使用SQLite的WAL模式
  9. waves服务器系统盘,Waves 新款小巧化 SoundGrid 服务器 Server One-C 和 Extreme Server-C 公开...
  10. er图转为数据流程图_draw.io for Mac(流程图绘制工具)