Node.js へのcontributeの仕方

qiita.com

このエントリは Node.js Adventcalendar の 1 日目のエントリです。

Node.js への contribute の仕方

Node.js の contribute は敷居が高いと思っている人がいるのかあんまり日本人が contribute をしているのを見ることが少ない。もっとコントリビュートする日本人が多くても良いんじゃないかと思っている。

これまでの Node.js では CLA にサインが必要だったりイマイチさくっとコントリビュートができないという問題があったが、 v4 になってからの Node.js はかなりコントリビュートまでの敷居が下がっている。

にも関わらず、少ないのは日本語の記事が少ないことも一つの要因だと感じているのでこれをきっかけにコントリビュートのやり方を抑えてもらって第一歩になるようにしてもらいたい。

Node.js のリポジトリの中身

Node.jsのリポジトリの中は以下の様な感じになっている。

nodejs/node
├── benchmark/
├── lib/
├── src/
├── deps/
├── test/
└── docs/

contributor が修正するのは主に下記の場所だと思っていて良い。

  • lib/ JavaScriptAPI が記述されている箇所、最もコミットが多い(と思われる)
  • src/ C++ で v8 や libuv への依存を直接呼んでいる所
  • doc/ API の説明が書かれている documentation のためのページ markdown が使われてる
  • test/ テストコード、最近 不安定なテストを修正しよう運動 が行われていて、ここもホットにコミットがある

この他にも所謂 README.md だったり、 .eslintrc みたいなファイルを修正することはあるけど、基本的にはこのような感じ。

lib/ へのコントリビュート

lib/ が一番コードの変更が多いと書いたがひとえに API に対して変更したいという要求が多いからだとおもう。APIは開発者が直接触れるところなので、そこへの変更は多くなる。

ただし、気をつけなきゃいけないのは、 lib/ の中のAPI を変えるっていう事は互換性に気をつける必要があるという事だ。経験上、互換性を壊すようなコミットはあんまり受け付けてくれない時が多い。互換性を壊す、ということにも色々あって、バグを修正して正しくエラーになる挙動にした結果、それまで無視して無理矢理動いていたコードが動かなくなったという話もあったりする。そもそも正しく動いていなかったが、ちゃんとエラーという挙動になることで互換性が損なわれてしまうという事だ。

こういうので揉めたりすることも勉強になるのでやってみると良いとおもう。疲弊するけどやりがいはある。

また、最近よくあるのがES5からES2015のコード変更だ。これに関してはコントリビュートしやすいし、やりたがる人は多い。ただし、これも気を付けたほうが良い。まだ V8 の JIT が ES2015 に最適化されておらず、愚直に ES5 で書いている方が速いことが多いからだ。

僕は Node.js を ES2015 のモダンなコードスタイルに変えるべく色々と調整してきたが、一番きつかったのは、既存でやってたgoogle-closure-lintereslintに変える修正だった。

github.com

結局この修正は色んな効果があって、みんながeslintに乗り換えてくれたおかげでtemplate string literalsやoctal literalといった新しい文字を持つES2015のコードもある程度は書けるようになっている。しかしやっぱり class 構文や letといった性能に影響があるものはlib/の中では書けるものの広くは受け入れられていない。

Promiseを返すコードにしてほしいというのも性能の問題が理由で受け入れられていない。Node.js のコアのコードは読みやすさや書きやすさよりも互換性と性能を追い求める傾向にある。

また、『これがあると便利じゃない?』みたいな一見便利に見えるようなコードも受け入れられないことが多い。

github.com

例えば 上に挙げたようなconsole.groupみたいなconsole API の拡張だ。これに関してはnpmで困っていないならnpmを使おうと言うのが Node.js のコアメンバーの意向だ。 Node.js のコアのコードはかなりbasic で必要最小限しか入れていない。

LESS IS MORE という言葉がある。これは「より少ないことがより豊かである」という意味の建築家の言葉だが、シンプルに機能を削ぐことでゴテゴテした機能をたくさん持つよりも結果として豊かになるという発想で、これを体現しているのではないかとおもう。なので、一見便利じゃない?みたいなのはコンセプトに合わず、拒否される事が多い。

コアでしかできないこと、コアには必要なことは何なのかを考えてコミットするとPullRequestが受け入れられやすくなると思う。

src/ へのコントリビュート

所謂 C++ レベルでの変更をする時のコントリビュート。ここはV8とかlibuvとかopensslといったライブラリを呼んでいる箇所であり、所謂 Fedor Indutnyや Trevor Norris や Ben Noordhuis や Shigeki Ohtsu といった重鎮が変更する箇所である。

僕はここにコミットしたことはまだない。ただし、コラボレータをやると分かるが lib/ レイヤの変更でできることよりもsrc/レイヤの変更でできることのほうが圧倒的に多い。特にBuffer周りの改善やnet周りの改善系はダイレクトに性能に響いてくるし、tls レイヤのエンハンスは性能とセキュリティというセンシティブな領域を攻めることができる。

Buffer を変更した場合は Trevor Norris, Ben に、 net/httpを変更した場合は Fedor Indutny, Ben に。 tls 周りは Shigeki Ohtsu, Fedor にレビューワーを選んで見てもらうのが良いだろう。

doc/ へのコントリビュート

一番わかり易いコントリビュートといえるだろう。 Node.js はドキュメントがダメだというのはこの前の Node学園祭での NodeDiscussion でも上がっていたが、 document はエコシステムとして周りが作るものなので、ダメだと思うならコントリビュートして欲しい。

docを修正するのが一番簡単で、敷居も低い。

ただ注意点としては、heとかsheみたいなgenderを表すような言葉は使ってはいけないという流れになっている。これはdocumentationにかぎらずだが、一番うっかり書いちゃうのがdoc/へのコントリビュートなので気を付けたほうが良い。

github.com

genderの他には宗教や能力の差、身体的特徴など、とにかく人を不快にさせるような言葉は使ってはいけないとされている。
難しいかとおもうかもしれないが、基本的にはAPI説明だけならそんな内容を書くことは少ないし、割りとチェックもされるので気軽にtypoを見つけてはコミットしたり、ドキュメントの間違いを見つけてはコミットすると良いとおもう。

test/ へのコントリビュート

testへのコントリビュートもまた盛んである。OS によってはコケたり、またタイミングが悪いとコケたりするコードのことを不安定なテスト、 flaky test と呼んでいて、これを撲滅する活動が盛んだからだ。

test フォルダ以下に {フォルダ名}.status という名前のファイルが有り、そこを見るとどれが flaky でどれが flaky じゃないかがわかると思う。

github.com

これを直すとかなり感謝されるし、取り込まれる可能性が最も高いコミットだとおもう。

また、 lib/src/ を修正したらほぼ確実に test/ を書くことが求められるので、常に test を書くクセが付くはずだ。

ここをコントリビュートの出発点にして欲しいと Node 学園祭に来た Rod Vagg も懇親会の二次会で言っていたので、間違いないだろう。

コントリビュートの細かい作法

Node.js はコミットする時にコミットメッセージに

<修正するラベル>: <修正タイトル> ※ 80 文字以内
修正した内容

を書く必要がある。Reviewed-By や PR-URL というラベルはマージする人がつけるという決まりになっているので、コラボレータになると習うはずだ。
僕の最近やったコミットではこんな感じになる。

github.com

また、参考までに僕の拙いメモで良ければこういうマージフローになっている。

www.evernote.com

コラボレータになると merge 権限もあるし master への push 権限も持つことになる、一番注意しないといけないのはうっかり master に push しちゃうことだ。とりあえず間違っていてもすぐに直るだろうが、 git の使い方が怪しければこれを機に見直す良い機会になる。

コア以外へのコントリビュート

コア以外のコントリビュートも盛んだ。僕のやってる evangelism とか benchmarking とかはコア以外で貢献できるタイミングだと思う。 evangelism は毎週の変更点やニュースをピックアップして website に載せるという活動だ。 benchmarking はまだあまり進んでいないが、 benchmark フォルダを修正したり、わかりやすくグラフにして見える化するという活動も含まれる。

最近は Node 学園祭とか学園祭をやってる間に溜まったタスクの消化で忙しく、あまりコントリビュートできていないので、是非みんなも参加して欲しい。

あと、翻訳も立派なコントリビュートだ。 Node.js の API の翻訳が古いと言われているのでそろそろ本腰を入れて翻訳活動を再開したいがどうしても時間がない。(やりたいという人達が集まってくれるとやりやすいのだが、、、)

最後に

いろんなことを言ったが、コントリビュートのやり方は様々だ。僕はやるようになって LESS IS MORE という考え方や英語力、またコアメンバーとの信頼等々色んな物を得たので是非みんなもやってもらいたい。もちろんこういうのは強制になるとつまらないので、やりたいという人達が有志でやるのが一番だと思う。

僕も大津さんも協力するので是非 Node.js をエンハンスする活動に参加してもらいたい。