如何打造规范的开源项目workflow

栏目: 编程工具 · 发布时间: 5年前

内容简介:一般开源项目正常的开发流程是:表面看起来没有什么毛病,但是要做一个那在多人协作的开发过程中到底会碰到哪些无法统一的行为?我们该如何解决这些问题?

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

  • 初始阶段
    • 创建仓库
    • 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-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等信息都需要记录下来,便于区别不同版本的新特性,然后手动维护记录通常容易忘记,导致这一部分经常没有持续的更新。

解决步骤

目前社区使用最广的方案是 Commitizenconventional-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 命令来进行代码提交了。

    如何打造规范的开源项目workflow
  • 项目安装:

    让你的项目让别人更友好的接入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默认发布的tag
    beta: 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

    添加 prepare hook

    {
        "scripts": {
            "prepare": "npm run build"
        }
    }
    复制代码

    然后执行 npm publish

执行 npm version 命令时会依次执行 npm script 中的 preversionversionpostversion 三个钩子,具体详情见文档

为什么要使用 prepare 而不用 prepublish ,在npm@4.x之后,建议使用 prepare ,具体详情可见声明

结尾

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

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

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

是不是更简单方便了呢?

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

github原文地址,传送门

参考文献


以上所述就是小编给大家介绍的《如何打造规范的开源项目workflow》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

劫持

劫持

玛丽•K. 斯温格尔(Mari K. Swingle) / 邓思渊 / 中信出版集团股份有限公司 / 2018-5-1 / CNY 59.00

《劫持》是一本探讨人与科技的关系的书,基于一位心理学博士20年的临床经验及其作为神经认知科学研究者的脑—电研究成果。在这本面向大众的科普书中,作者以深入浅出的方式,探讨了手机、电脑等便携式数字设备及让人“永不下线”的互联网对现代人尤其是青少年大脑的影响,从神经认知科学和精神分析的角度,有力地证明了数字媒介与大脑和人类行为的关系,探讨了手机等如何对人的大脑进行劫持或操控,并给出了自己作为从业医师的实......一起来看看 《劫持》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具