为 Node.js 贡献你的力量

1,192 阅读6分钟

Node.js 作为一个世界级的 Javascript 运行环境,能为它贡献自己的代码,运行在全球各地的服务器上,真的是一件很令人兴奋的事情。

从上个月开始,我提交的好几个 PR 经过 review 之后,绝大部分都被接受进入了主干,作为一个初来乍到的萌新 Contributor,想写一篇文章来分享一下自己的经验吧。

一、提交 PR 的大致流程

Node.js 目前主代码库是 nodejs/node,这里涵盖了绝大部分的代码,包括C++编写的runtime、JS编写的基础库、测试代码、性能测试以及文档和指南。

提交贡献的指南可以参考:CONTRIBUTING.md,建议英文好的同学直接看原版指南。

1、Fork

首先要做的第一件事当然是 fork 到自己的仓库里,然后 clone 到本地,并且把主仓库添加进去:

git clone git@github.com:username/node.git
cd node
git remote add upstream https://github.com/nodejs/node.git

2、Branch

有了本地仓库之后,就可以 checkout 到一个新的分支:

git checkout -b my-branch-name

随后你就可以对代码进行任意修改了。注意写下的任何文本性质的东西又应该符合 Style Guide,包括任何注释和文档。

(至于改什么地方?怎么改?哪些地方需要我们做贡献?这个问题请看第二部分。)

3、Commit

修改完毕之后,就可以提交 commit 了,在 commit 之前,请先确认好自己的名字和 Email 是否配置正确:

git config --global user.name "Nobody"
git config --global user.email "nobody@example.com"

注意这里的名字最好使用自己的真实姓名,中国人的话名在前,姓在后,比如 "Zemin Jiang"(逃

然后进行 commit :

git add my-changed-files
git commit

commit message需要遵守下面的规范:

1、第一行文字需要简单地描述 commit 信息,不超过 50 个单词,非必要情况不能出现大写字母,开头应写上涉及到的子系统的名字。下面是几个范例:

  • net: add localAddress and localPort to Socket
  • errors: fix typo in comments

2、第二行空白;

3、其他行保持在 72 个字符之内;

4、如果你的提交修复了到某些 issue 或者有一些参考引用,记得使用 Fixes 或者 Refs 来标注他们,例如:

下面是官方给出的一个 commit message 范例:

subsystem: explain the commit in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way, `git log` will show things
nicely even when it is indented.

Fixes: https://github.com/nodejs/node/issues/1337
Refs: http://eslint.org/docs/rules/space-in-parens.html

4、Rebase

使用 git rebase 将你所做的修改和主仓库保持同步,确保你的修改没有和主分支冲突:

git fetch upstream
git rebase upstream/master

5、Test

Node.js 项目里有十分完善的自动化测试,任何 bug 的修复或者 feature 的添加都应该经过完整的测试。

在 Unix / MacOS 执行完整的构建、测试以及代码格式检查:

./configure && make -j4 test

Windows:

./vcbuild test

任何对代码的任何修改,都必须保证测试完全通过。

另外还有几个 tips:

  • 如果只想检查代码格式,执行 make lint 或 vcbuild lint 即可;
  • 如果没有修改 runtime 环境的代码(lib 和 src 目录下),比如只修改了 test 或者 benchmark 下的代码,那么就不需要重新执行漫长的构建流程,直接进行测试即可:python tools/test.py -J --mode=release
  • 与 2 同理,任何对于 lib 或 src 目录下的修改,都需要进行重新构建。

6、Push

把修改提交到自己的仓库,没什么好说的。

git push origin

7、Pull Request

提交 PR 的时候务必记住遵循官方给出的 PR 范例,其实基本上就是 commit message 的内容加上一个 checklist,以及附注涉及到的子系统即可。例如我之前的一个 PR(errors, buffer: Migrate buffer errors to use internal/errors by starkwang · Pull Request #13976 · nodejs/node):

8、讨论和修改

PR 提交之后,很快就会有 Collaborator 来 review 你的代码,并且给出意见和建议,绝大部分 PR 都需要多次修改后才会被接受,所以不要因为 review 要求的改动太多而沮丧。

在此期间的任何修改都记得 rebase,以保持只有一个 commit 的状态。

git add my-changed-files
git commit
git fetch upstream/master
git rebase upstream/master
git push -f origin

9、Landing

PR 被 merge 要求至少有一位 Collaborator 通过了这个 PR,且通过了持续集成(CI)测试。之后如果没有其他人提出异议,那么它会在不久之后被 merge。(一般是48-72小时,以确保大部分成员都能看到这个 PR)

有一些比较大的 PR 会直接被 merge 进入主分支,例如 errors, buffer: Migrate buffer errors to use internal/errors by starkwang · Pull Request #13976 · nodejs/node

当然也有一些比较小的改动,这时一般会有一名 review 你代码的 Collaborator 代替你向主分支提交 commit,不过你的信息依然会完整地保留下来,随后这位 Collaborator 会在 PR 里附上类似 "Landed in xxxxx" 的评论,并且关闭这个 PR。例如 errors, url: port url errors to internal/errors by starkwang · Pull Request #13963 · nodejs/node

最后,你就成为了一名光荣又伟大的 Node.js Contributor 了!

二、有什么可以做的吗?

作为开源项目,Node.js 和商业项目不太一样,它并没有一个十分详细的 Todos 列表,你可以随时修改它的任意地方,并且提交 PR,包括但不仅限于:文字错误、文档修改、增加单元测试、修改某些方法的实现(一般要确保性能有提升)、修复某些 issue 提到的 bug、某些 tracking issue 里提到的任务列表……

所以我这里也并没有一个明确的答案,总之多看 issue、多看别人的 PR,多看代码,总能发现一些需要我们做的事情。比如你可以查看所有具有 “feature request” 标签的 issue,并且在其中找找有没有什么可以做的:Issues · nodejs/node

我最近在做的事情就是把内置模块的错误,迁移到使用 internal/errors.js,这样可以统一管理 Node.js 产生的错误码,以及标准化错误信息,而不像之前那样随心所欲地直接扔一个 Error 和一个很随便的 Error message 出来。

三、关于开源

在给 Node.js 做贡献之初,我一直觉得 Node.js 的项目成员都是相当高傲的,毕竟维护了这么火热的一个大型项目,一定都是很牛很牛的人,所以一直有一种 “真是麻烦您给我 review 代码的感觉”,直到看到一位成员说的这样一段话:

开源是一项持久而又伟大的工作,一个开源项目的成功,需要的不仅仅是勤劳的维护者,更需要成千上万分布在世界各个角落的 Contributor 们,他们之间的合作产生出了一个又一个造福全人类的开源项目,让我们为开源精神干杯!