NodeConf Adventure 2015 に行ってきました。(三日目、四日目に起きたこと)
さて、三日目と四日目に起きたことを書いていくよ!
三日目も同様にアンカンファレンス形式でスタート
ホワイトボード見てもらって分かるかもしれないけど、 Diversity, Documentation, JS Modules, Streams, FrontEnd Packaging, Error Handling などが三日目の議題だった。
JS Modules の話
bower 使ったり jspm 使ったり、 はたまた npm + browserify 使ったりと戦国時代状態のフロントのパッケージモジュールに何使うべきかっていうディスカッション。まだみんないろいろ試してる感じだったけど、 npm + browserify と monolithic な JS library の相性が悪くて、どうするべきかっていう話が一番面白かった。
Workshop 会場にて: package module どないすんねんっていう話が出てる、 npm + frontend か jspm か、、、とにかく bower 嫌いって言ってる。
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
jspm, npm + browserify, bower, webpack でどういう時に何を使うの? っていう話
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
依存ツリーがひどくなって、沢山モジュールロードしたけどそれ毎に jquery とか lodash があるとかひどい状況だからそれだけは回避したいという話。 npm + browerify だとどうなるのか。
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
ここでの学びとしては、 npm + browerify 派は もう絶対に monolithic な library は使うべきじゃないって言うこと。 like jQuery lodash
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
React を利用した結果、全てのページをモジュールの塊として表現できるようになってきて、 その考え方が npm の module と相性が良いという話
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
というわけで、全体のエコシステムは npm + browserify とか npm + jspm に向きつつも、 jQuery ライクな monolithic な ライブラリーはやめて unix philosophy な小さいライブラリを作っていくのが常套手段という感じだった。
ただ誰も WebComponents の話をしてなくて、 ES6 modules とか browserify の話は出てくるけど、 WebComponents で ページのコンポーネントを作るという考え方も本来はあるはず。CSSもそのパッケージモジュールに載せたいっていう話が多かったけど、NodeConfでは誰もWebComponents の話はしてなかったのが気になった。
ただ、果たして WebComponents のHTMLにsemanticsを持たせて、moduleに分割する考え方と全てをjsでやる npm + browerify 勢は理解しあえる日が来るのだろうか
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
Error ハンドリング
Node.js のエラーハンドリングという普遍的なテーマについての議論、 domains についての話と zone っていう strongloop 製のライブラリの紹介がメインだった。domains があまり使えないっていう話は mozaic.fm でもしたけど、ここでも同じ議論。
error の会。
まずは error には user handle error と system error みたいな unhandle なエラーが有るということ。
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
domain が必要になるようなケースは edge case なのではないかという話
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
zones #nodeconf / “StrongLoop | Announcing Zones for Node.js” http://t.co/AmuPYhA9KQ
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
Zoneの話、面白くて色々見てたら Dart にも Angular にも同様の機能があったりして、ちゃんとやってみてもいいかもって思った。
中身の構造を見てみると domain とすごくコンセプトは似ているんだけど、全く違った実装で作られていて、 zone によって限定された範囲をトラップするためにsetImmediate/setTimeout を拡張したり割りと global を拡張してるので、すごい力技で実装されていた(この力技のところが逆に受け入れがたい印象も受けた)。
あと、『そもそも例外が上がった時点で終わりだろ、本当にやばい時以外、例外上げるべきじゃない』っていう議論もあった。
Interview with @bad_at_math
DeNA SF に転籍した bad_at_math さんこと、篠崎さんとエラー/例外の話をした(日本語)。
俺: 「例外が上がった時点で終わりっていうのってどうなんですかね、ちょっとそうも行かない気が」
BAM:「まぁでもある程度わかるかなぁ、本当にやばい時じゃないとそういう時に陥らないように設計してる」
俺:「例えばmysql へのアクセスでたまたま接続不良で例外上がったりしますよね、そういう時どうするんですか」
BAM:「例外の中にも種類があって、絶対復旧不可能な奴とリトライで対処可能な奴でいくつか種類がある。この中でも絶対復旧不可能な奴は本当の例外として扱うべきで、こういう時はアプリケーションのプロセスが生きててもしょうがないからそういう例外が上がった時点で終わりっていうのは分かる。」
BAM:「一方で一時的な接続不良みたいな奴はリトライしたら大丈夫っていうパターンが多いからそういうのはプロセス終わりにしない、ちゃんとMySQL で言うと戻り値のエラーの種類を見分けてどうするのか決めてる。」
※ エラーの種類一覧 http://dev.mysql.com/doc/refman/5.6/en/error-types.html
俺:「なるほど、ミドルウェアのドライバーから上がった例外をちゃんと適切にハンドリングできているの初めて知ったかもしれないです。domainとかは使ってます?」
BAM:「domainかなり助けられるケースが少ないんだよね。ほぼほぼ使ってない」
最後に (Ex含む)DeNA チームでパシャリ
Diversity の話
この話が NodeConf 行ってきた中で一番面白かった Diversity の話。
Diversity っていうのは "多様性" っていう意味で、どうやって多様性を認める文化にするかっていうコミュニティ運営の話だった。
技術的な話というよりは本当に運営の話で、OSSというかインターネットのコミュニケーションは相手の顔が見えないとちょっと語気を強めに言う傾向にあって、そういう事がこのコミュニティの中であってはいけないし、どんな人でも発言できるコントリビュートを表明できる必要があるという話だった。
初心者も何年も関わっている人もフラットで平等に扱われるべきだし、間違っても個人の尊厳を深く傷つけるような行動はあってはならない。一人の意見を尊重しようという話。
詳しくはここにまとめてくれている人がいるので詳細を知りたい人は読んでみて欲しい。
Challenging Diversity at NodeConf | The True Entrepreneur Corps
簡単に説明すると、
1. 全員が共通して持っている弱みを把握しよう
他人を犠牲にしてまで自己を過剰に防衛する事をやめよう、という話。
実行可能な批判は受け入れるべきだし、その批判に対して過剰に反応して防衛したり攻撃するのは避けるべき。
常にインプットをコントリビューションの一部として好意的に捉えて維持するのは難しいんだけども、個人の考えを尊重するべきだし、間違っても人のプライドを傷つけるような事があってはいけない。
2. Collaboration > Competition
競争よりも協力。
必ずしも競争が悪ではない、健全な競争は受け入れた方がいい。でも競争が問題をストップさせる事もある、そういう時は議論の視点を元に戻して考えなおすべきだ、という話だった。
3. 模範によって導く
npm には guys jar っていう制度がある。 "Guys" っていう言葉を男女混合のグループを指す意味で使ったら $1 払って jar に入れるっていう制度だ。
(これは opt-in policy なので強制じゃなくて任意参加らしい)
コミュニティのリーダーは率先してそういう模範を示して欲しいという事だ。 guys jar は単なる罰ゲームじゃなくて、率先してそういう事を表明する事で gender の差をちゃんと自覚してみんなを導くという行為。
こういうのは Node にもあってもいいんじゃないかという話が出ていた。
結果として、ドキュメントのための WG ができて、そこでドキュメントに記述していい言葉が決められることになった。
以下がちょっとした例。
ユーザーを指すときの言葉として使っていいものと使っちゃいけないものの例。
OK: "they", "their", "them", "folks", "people", "developers", "cats"
NOT OK: "his", "hers", "him", "her", "guys", "dudes".
4. 「Ouch」っていう発言を信頼しよう
コミュニティのメンバーが自分の世界とは違った問題を報告したとする、そういう時に無視するべきではない。
例えば npm ユーザーはたまに Windows マシンで npm を使うことの難しさに不平不満を言う事がある。
Windows の問題はしばしば文化的なジョークとして捉えられる事がある。だからこういう Windows の問題は無視されやすい。でもそういうのは起きるべきじゃない。そういうのがずっと積み重なるといつかコミュニティは廃れていく。
npm ではこういう Windows の問題は出来る限り対応しているし、一般的なルールとして、聞く => 聴く => 反応する の順で発言は対応するべきだという話だった。
こういう話が行われているメタなカンファレンスを僕は知らなかったし、この議論はすごくおもしろかった。
僕はローカルコミュニティのリーダーをやって一年になるわけだけど、こういう目線の話をちゃんと自覚して考えたことがなかった。 Diversity の話はちゃんと記憶にとどめて活動していこうと思った。
Performance Monitor Session
パフォーマンスモニタリングのワークショップで、メモリリークの特定とか、 CPU 100% になったときにどこが悪いのかを見つける方法の話だった。
dkhan の話は具体例も多くて面白かったけど、途中から StrongLoop の人が俺たちのやり方紹介するよって言い出して解説が始まったのがすごく面白かった。
cpu profiler をとって、frame graph で重いところを見つけて、 IRHydra で v8 がどういう風に optimize してるかを見るっていうのが一番良いという話。
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
Tessel Hack
tessel のワークショップがあったのでそこに参加して色々やってきた。
tessel を hack してる
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
tessel で撮った写真 pic.twitter.com/vNkWlMzq4s
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
tessel 入門して 15 分でカメラで写真が撮れた!
— Yosuke FURUKAWA (@yosuke_furukawa) June 13, 2015
Tessel 本当に素晴らしくて、レゴブロックみたいにスロットに何か差しこむだけで色んなものを動かすことができて本当に面白かった。
カメラで撮影するだけだったらサクッとできたし、 @maxogden と話した時に Max は自転車に取り付けてずっと風景を撮影させてるとか言ってて、むちゃくちゃ面白そうだった。
この辺は勉強会でも取り扱ってもいいかもなぁと思った。
Tessel, Performance Monitoring の人達とパシャリ
最後のキャンプ
最後のキャンプで NodeFest の話をしてきた。
『NodeFest は 11/7(土) に実施する予定で、場所は渋谷、もしも NodeConf の人達が来てくれたら寿司をおごるよ』って言ったら
みんなが「ワー!!」って拍手してくれた。
Thank you all for an amazing experience at @nodeconf! See you on the interwebs #pandaqueen #NodeConf #InPictures pic.twitter.com/oJPLwO7mIv
— Thomas Watson (@wa7son) June 14, 2015
本当に色々キャンプとしても面白かったし、色んな話ができてめっちゃ楽しかった。
来年も行けるといいなぁ。
Great talk about package management
@nodeconf pic.twitter.com/nGNXb0kL6w
— Kevin (@kyoukhana) June 13, 2015
Mixing #NatureTechnology in @nodeconf adventure pic.twitter.com/y7mIFtqHEK
— Citrus Taller (@CitrusTaller) June 12, 2015
#nodeconf pic.twitter.com/AofPPcdnlD
— tylerbushnell (@wunderlinks) June 14, 2015
@design48 @nodeconf @mrbrookman #nodeconf pic.twitter.com/sOKrjkpbTg
— =^._.^= (@maxogden) June 14, 2015
Node.js の API をジェスチャーして当てるっていうゲームがめっちゃ楽しかった。知らない人とでも仲良くなれるし、俺の英語力は低いからジェスチャーの難易度が高くなってみんなからお前がやると面白いって言われた。
— Yosuke FURUKAWA (@yosuke_furukawa) June 14, 2015
process.nextTick とかどうやってジェスチャーで表すねんと思ったけど、俺が変なジェスチャーしたら奇跡的に当ててくれて、そこからみんなが process APIの時に俺の真似をするっていうコラボレーション。
— Yosuke FURUKAWA (@yosuke_furukawa) June 14, 2015
NodeConf Adventure 2015 に行ってきました。(一日目、二日目に起きたこと)
NodeConf に行ってきました。 NodeConf っていうのは Node.js のための勉強会です。 io.js の中心人物である mikeal や、 npm のCEO である izaacs 、 hapijs author であり、先日 Walmart を退社した Eran Hammer など、そうそうたるメンバーの中でディスカッションをしてきました。
NodeConf Adventure とは
NodeConf Adventureはいわゆる発表者がいて、聴講者が聞くっていうスタイルのカンファレンスじゃありません。
なんというかものすごくメタなカンファレンスで、ワークショップとノウハウの共有をメインとしたディスカッションのための場所です。 アンカンファレンスっていう形式ですね。
Hello NodeConf! pic.twitter.com/MHBVi6Jg4c
— Yosuke FURUKAWA (@yosuke_furukawa) June 11, 2015
午前中に主催者である mikeal がロッジに全員を集合させます。
その後で参加者全員に何が聞きたいかを決めてスタート。
みんな isomorphic とか ES6 とか IoT とか microservices とか言って、発言していて、 substack が 「P2P hack しようぜ」って言ってたのが面白かった。( mikeal は興味なかったみたいでスルーされてたけど。)
Workshop に参加中。
P2P
HW on ARM
Native Modules
io.js TSC Panel
ES6
NODE Strategy
Types in JS
Documentation
Debug
のとりあえずどれからやるー?みたいな感じ。全部やってくれ。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
それぞれのトピックごとに場所を分けてスタート。
isomorphic
isomorphic って言ってもメインは サーバサイドレンダリングと React っていうよくある話だった。やっぱり viewの機能をサーバサイドで使えるようになったこと、初期表示のスピードが通常のSPAより改善できること、SEOによるアクセス向上などの話がメイントピックだった。
こんな感じ nodeconf pic.twitter.com/s8A7T1FFMM
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
React 使ってる人 10人位が手を挙げる
サーバサイドレンダリングまでやってる人 => 2人くらいしかいない。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
framework から脱してロックインから抜けだせという意見もある。過激派だ。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
まぁ確かに isomorphic をやったら、 ES6 とかで書くとか io.js でできることはむしろできなくなるという問題があるのは分かる。まぁbabel使うのかもしれないけど。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
面白かったのは、 browser で module の解決とかどうするのかっていう話で browserify から ES6 に話は飛び火して、 isomorphic を実現するための鍵としてやっぱり ES6 module なんじゃないかっていう話が一番面白かった。
browser に真のmodule を持ち込むのってどうするのか、という話で、めっちゃ面白い。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
今は browserify っていうか commonjs が主流だけど、これをどうするのか、あと HTTP/2 とかが来たらどうなるのかっていう議論をしていた。(もっと英語で話せるなら日本だとこういう議論してるって言えたんだろうけど、議論に割り込む勇気がなかった)
あと、ここでも fluxible 使ってるっていう人とか meteor で頑張ってるっていう人もいたけど、一人自作したっていう人が居てその人の lighter っていうライブラリを教えてもらってた。
React + isomorphic の ワークショップ
React と isomorphic のワークショップをやってたのでそこにも参加してきた。ワークショップ教材は以下のとおり。
Reactと fluxible つかって簡単なカウンターをみんなで実装しましょうっていうノリ。 1時間無いのと wifi が不安定すぎて一問しか進まなかった。 終わった後でOliverっていう isomorphic workshop をやってた方と話したけど、
僕:「fluxible どうよ?」
Oliver: 「isomorphic library の中ではいいと思うけど、 isomorphic 辛い」
僕: 「何が辛いの?」
Oliver: 「isomorphic でクラサバどちらでも呼べるようにするのがたまに面倒、ブラウザにしかないAPIを呼んじゃうと台無しになるし。」
僕: 「たしかに。でもfetchr とか routr みたいな isomorphic library 使っていれば、そこまで大変じゃないのでは?」
Oliver: 「まぁそうなんだけどね、まだ慣れてないのがあってうっかりすると呼んじゃうんだよ」
みたいなことを言ってました。ちなみに Oliver とは同じ部屋であることもあってすごく仲良くなった。
Oliver とパシャリ
Node Stability の話
Node.js の安定性っていう io.js Collaborator としてものすごく興味深いトピックに対しての議論だった。
こんな感じ pic.twitter.com/cm9ROk6Nty
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
node stability なので、何も変更しないようにしよう提案 => それまた fork されるパターンというツッコミを izs がしてた。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
Code Coverage
npm module の Smoke Test
の2つはとりあえず安定性のための鍵っぽい
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
Nodeを Stable, current, beta, canary に分けようという提案
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
izaacs とか mikeal とか Fishrock とか Chris Dickenson とかのこれまでのコラボレーター達が今後どうするべきかについて議論してた。
最終的に議論の成果として、現時点で mikeal が思うバージョン階層について説明してくれた。
- Stable(LTS) 絶対変わらないAPIでずっとサポートされるもの
- Current 現在のバージョン
- Beta 次のバージョン RC1とかRC2みたいなバージョン
- Canary nightly build、毎日ビルドされるもの
に分ける。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
これを io.js の issue に上げて今でも議論中。
こんな感じになる予定らしい。
ES6/7 の話
みんな ES6/7 の関心が高いようで、やっぱりここでも babel の存在感は大きかった。
特に議論になっていたのは、 async-awaitの話、decorator の話、function-bind の話で、みんな ES7 の話をしていた。
yield generator と async await の違いはだから、 yield generator は generator を作るためのもので非同期関数のためのものじゃないんだよっていう話。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
async-await こそが 非同期関数を呼びやすくするための鍵
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
async await で 例外が上がったら、 try catch で catch できる、これこそがみんながやりたい事だと。 Promise の catch はいらない。わーお!という流れ。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
Decorators 使いたいよねぇという話でもうみんなの興味は完全に ES7 だ。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
特に、 async-await と generator-yield の使い分けの話がメインだった。
NodeConfだとまだ async-await を使って ES7 やるぜっていう人はそこまで多くなかったけど、 io.js だと generator-yield がネイティブに使えるのでそれを基本にやってる人はまぁまぁ多かった。
ES6 workshop
ES6 を io.js を使って動かしてみようワークショップ、これも Oliver さんが担当。
これ実は微妙に手伝ってて、このリポジトリに io.js の ES6 の issue 投げてたり、 Oliver と discussion してたら、何かわからないことあったらフォローしてくれと言われたので、注意深く聞いてた。
これに関しては知っている事も多かったので、時折Oliverを補足したりしながら進めることができた。
Interview with Chris and Fishrock
終わった後で、 io.js の TC member であるChris Dickenson と Fishrock123 と一緒に今後の io.js について話した。
俺:「今って Chris はどんな事を io.js に入れようとしてるの?」
Chris:「Code Coverage を取れるようにしようとしているよ」
俺:「おお、それって io.js の test のカバレッジ?」
Chris :「そうそう、(画面を見せてくれる)」
俺:「へーすごい。isutanbul で取れるようになるのかー。」
Chris:「今だと tls-legacy があまりカバレッジ良くないとか出てるよ。」
俺:「Fishrockは今何やってるの?」
Fishrock:「バグが出たら直す、PRが来たらレビューする、そればっかりやってるよ。」俺:「ところで前に isomorphic の issue 上げたんだけど、あれってどう思う?ちょっとセンシティブな話かなぁ」
Fishrock:「うーん、基本的にユーザーランドで解決できるようなものは解決してコアはシンプルにっていうのがいいかなぁ」
Chris:「Agree、ただ url module とかどうするべきかねぇ。」
Fishrock:「url は what-wg で出てる奴が仕様になったらそれを採用するべきかなって思ってるよ。後は他の下の方の Blob とかは対応するべきだと思ってる。基本的に既にコアモジュールになっていて、what-wgが出してるものに関しては出来る限り isomorphic にするべきかなって思ってる。」
Chris:「Streamはどう思う? what-wg stream が出てるよ」
Fishrock:「うーん、どうかなぁ、、、」
俺:「fetchは?」
Fishrock:「Fetchはやりたくないかなぁ、僕は新しいモジュールは追加したくない。」
俺:「fetchは http.fetch みたいな関数では?」
Fishrock:「それでもユーザーランドでできるならそっちのほうが、、、」
俺:「ところで Stream ってなんであんなに what-wg の奴は API が違うんだろうね」
Chris:「僕らのStreamはFile IOとかNetwork IOの性能面のケアをすごくしてるからね、 what-wg の方は ウェブのインタフェースとして提案されていて、そっちの使い方に特化してるからじゃないかなぁ」
俺:「なるほど、そうなると Stream は難しそうだね、 what-wg stream の方、今 promise の配列だし、、、」
Chris:「そうなんだよね、さすがに EventEmitterベースを変えるつもりは無いし、 性能面はNodeの優先事項だしね。」
Chris はめっちゃ気さくな人で、 Fishrock はちょい堅物の若者っていう感じだった。
Chris とパチリ(Fishrock 帰り際に捕まえられなかった、でも良い奴だった)
レクリエーション
夕飯を食べていたら急に MaxOgden と substack が「お前ら!ゲームやるぞ!!」って言い出したので参加してきた。
この広いキャンプの中でwifi pointを隠したからそれを探してそのwifi pointに接続しろ、そのwifiのLANの中にいるマシンが何かのプロトコルを使って画像をstream配信してるからそれの画像を受信してスクショしろって言われた。
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
wifi見つけてからIPアドレスのマシンに行くと、JSのファイルがあって、中身を読むとrtspのアドレスが書いてあった。この短い時間で rtsp を解析するのかと思ってたら、Skypeがrtspを解析できたので、Skypeから画像をゲット。見事我々の勝利
— Yosuke FURUKAWA (@yosuke_furukawa) June 12, 2015
まとめ
- isomorphic で fluxible が人気、 meteor も使ってる人多かった
- ES6へのみんなの関心は ES7 に移ってた
- Node Stablity という事で安定バージョンをどうやって提供するか提案された
- isomorphism の話を Fishrock, Chris として何となく彼らが思っている事がわかった
- レクリエーションゲームで勝利!!
続きは三日目と四日目に起きたことを書くよー!
YAPC で Node.js のトークに応募しました。
Node.js 日本ユーザーグループ代表の古川です。
YAPC でまだ話せるのかは分からないのですが、せっかくなので宣伝させてください。
YAPC というイベントでトーク応募しました。
Node.js と io.js の話はこのブログでずっと話してきたんですが、ある程度まとまってきた所で振り返って話をしようかなと思っています。 日本ユーザーグループ代表の僕と 先日 io.js の技術委員会にノミネートされた 大津さん (@jovi0608) とでこれまでの Node.js の話と io.js の fork 騒動、 そして今後の Node.js という流れで話そうと思っています。
細かい部分は決めていませんが、これまでの流れをおさらいしつつ、最後は二人でパネルディスカッション形式で話しつつ、会場からも広く質問を受け付けるような形で進行できるといいかなと思っています。
聞いてみたいという方がいたらTwitterやFacebook、はてなブックマークなど、何でも良いので押してください。何卒よろしくお願いいたします。 m(_ _)m
何故 YAPC ?
YAPC には Perl 含めて OSS と深く繋がりがある人が多いからです。 OSS はかなり特殊なプロジェクト進行の形を取っています。参加者の皆さんは何かしらの OSS を使っている事が多いです。
Node.js / io.js にかぎらず、 Docker と CoreOS とかも袂を分かつようになりました。CoreOSの場合は fork ではないですが、基本的な方針が受け入れられないという所謂 "音楽性の違い" のような事が原因で分裂が起きるのは実は特に今始まった話じゃないです。
OSS に関わるみんなが OSS をどう進めていくのがハッピーなのかを知る、一つの教材になるのではないかという思いでトークを応募しました。
YAPC で伝えたいことは?
僕らが YAPC でお伝えしたいのは、
- 何故 fork 騒動が起きたのか
- Node.js/io.js のこれまでとこれからどこに向かうのか
- OSS をどう進めていくのが良いのか
の 3 点です。
io.js のコアメンバーがやろうとしたことは一つで「コミュニティドリブンの開発スタイルをPull Requestしたかった」という事に尽きます。
結果としてうまく推移し、Node Foundationに統合という方向で話はまとまりつつあります。既に githubには、両方を運用する Nodejs organization ができています。
ある程度コミュニティの力もあって、分裂前よりも統合後の方がよりコミュニティの意見を得やすく、また情報の発信もスムーズに行われるようになってきました。
Node.jsのこれから
これからどうなるのか、実は僕もそこまで知りません。おそらくコアメンバーでもどうするか決め兼ねているんじゃないかと思っています。今ロードマップに上がっている事、Next Generation リポジトリで議論されている事を踏まえて予想図を描こうと思っています。
その予想図を描くために、これからサンフランシスコに行ってきます。 NodeConfっていうカンファレンスがあるんでそこで話を聞いてきます。
向こうではワークショップも多くて、 isomorphic の web application を学べるワークショップがあったり、 ES6 のワークショップがあったりと楽しそうなので、面白そうな話があれば展開することも忘れずに行ってきます。
Node.js と io.js の統合は最終局面へ
いくつかこの何日間でニュースが出ているので紹介します。
ちなみに、 io.js と Node.js のニュースに関してはこれまで2つ書いたので、まだ良く知らない人はそれをまずはご一読ください。
yosuke-furukawa.hatenablog.com
yosuke-furukawa.hatenablog.com
さて、次の展開へ、という事でいくつか話があります。
「Join the Node Foundation?」 というissueが mikeal から提案される
issue 本文を翻訳したものを貼っておきます。
Node Foundationのためのすべての文書が揃った。
- TSC Charter (技術委員会の目的)
- Development Policy(開発ポリシー)
- Convergence Plan(移行プラン)
- Project Lifecyle (Working Groups Definition)
- WG Merger (List of working groups and how they will be merged)(各ワーキンググループの統合先)
gistの内容はつまり、「Node Foundationのガバナンス構造は io.js のガバナンスとほぼ一致している」という事を示している。実際、全ての文書を記述している最中に我々のポリシーを盛り込むために文書を改善させたし、より良い文章が作られていった。新しく "統合された" node プロジェクトは初期リリースターゲットとして、io.js master に入っているものをベースに、node.js からの変更はポーティングされてリリースされることになるだろう。
我々にはfoundationが必要であると私は思っているし、Linux Foundation は Node Foundation を基準とした構造として理想だ思っている。その理由はここに書いた。io.js を node.js と統合して、Node Foundation へ移行するかどうかを実際に決めるのは 今 しかない。
以前我々が約束した事は以下のとおり:
- GitHub organization は "node" もしくは "node-foundation" などに変更する事
- 統合作業が起きている間は io.js はリリースし続ける事
- TC は TSC (技術方針委員会) にそっくりそのまま移動 (人数が多いのでGoToMeetingにswitchするしかないかもしれない。)
- node-convergence リポジトリを 新しい organization の "node" として移動する事
明らかに多くの技術的なタスクがあるので、 新しく統合されたnodeのリリースができるようになるまで、io.js のリリースを継続的にし続ける事になるだろう。新しいリポジトリへの追加は継続して行われる事になるが、上記にアウトラインとして書いたことはすぐに実行されるだろう。
ワーキンググループでは、node.jsの資産へ適切にアクセスできて、ワーキンググループへ資産が移るように決まるまでの間はio.js としての活動は継続して行う事になるだろう(organizationの名前は変更されるが)。
P.S. プロセスにおいてはワーキンググループは自律している。もし TSC が io.js を Node Foundation に移動したという決定したとして、移動した後、 foundation の外にWGを移動させられるような事は断る事ができる。これは単に organization を移動することへの決定への制限になる。
とまぁこんな感じです。つまり、統合された際に io.js の開発はこれまで通りコミュニティドリブンで行われ、ワーキンググループもこのままで変更されません。
基本的にはio.js側の運営をほとんどそのまま引き継いだ形になります。
ちょっとこのissueの中であった反対意見を上げると:
- オープンガバナンスモデルのLive Stream配信がされなくなるのは困る(GoToMeetingはアーカイブ配信しかしない)
- 先に参加を表明して、後からコードをマージするのは問題が起きる可能性がある。変更がfixされてから(node.jsチームが変更をもう追加しないという状態になってから)参加するようにしないと後から彼らにとって都合の良い変更が勝手に加わる可能性がある。
- Node Foundation が割りとガバナンス志向なところが気になり、プログラマフレンドリーなのか気になる
というものです。僕の中ではどの意見も杞憂、もしくはそこまで強い意見じゃないかなと捉えていて、後は比較的好意的な意見が多いです。
今も議論は継続中ですが、反対意見/疑問があるならこの段階でしたほうが良いです。風向きは統合に対して吹いているように見えます。
おそらくこの issue で疑問や反対意見が出なくなったら本格的に統合が始まると思います。
どうやって統合するつもりなの?
統合に関しては、既に統合プランが出ています。
ほとんど上に書いてありますが、 まず人で言うと、nodeのコアチーム(Julien Gilli や jasnellら)とio.jsのチーム(Rod Vaggやmikealら)は統合されることになります。両方に属している人もいるので2倍とかにはなりませんが、一つの大きなチームに変わります。
リポジトリは一旦 io.js も 新しいnodeも同じorganizationの下(node もしくは node-foundation)に置かれる事になります。統合は時間がかかる可能性があるので、 新Nodeへの統合を行いながら並行して io.js がリリースされ続ける事になるでしょう。
新nodeのバージョン番号はどうなるの?
恐らくですが、 v3.0.0 になると思います。これには バージョン番号の重複問題が懸念として上がっています。
io.js は2015年の5月11日、現時点で v2.0.1 です。リリースされているバージョンと重複した場合、npm の engines の指定やnvmやnodebrewのようなバージョンマネージャが壊れてしまう懸念があるので、バージョンを重複させるような事はしません。新nodeは現行の v2.0と被るような事はしないので、おそらく v3.0になると思います。 もしも io.js がさらに先に進んで v3.0 が統合前にリリースされてしまった場合は v4.0 になる可能性もあります。
とりあえず認識しておいてもらいたいのは、現行のリリースバージョンとは被ることが無いということです。
この図が分かりやすいです。 (統合したものはNode v3.0 に読み替えておいてください。)
次の新しいnodeの名前はどうなるの?
元のNode.jsに戻ると思います。ただそうなると、Twitter IDとかlogoとかwebsiteのドメインとか作り直しに近いので、まぁそうなったらそうなったでしょうがない感じはしますね。今丁度 Website WGでは new.nodejs.org みたいな話でドメイン名の検討も含めて議論中です。
今のコアメンバーの思いは?
そこまで意思を全員が表明しているわけじゃないですが、基本的には統合に向いています。ちょうどこの調整に対しての一番の功労者である、 mikeal はブログの中で以下のように述べています。
僕達には foundation が必要だ。 彼らは準備をしているし、僕らに参加して欲しいと思っている。僕はこの foundation が io.js にとって理想の構造になっていると思う。さらにボーナスとして、僕らには io.js と node.js のコミュニティの分断と混乱を終わらせることができる。僕らは理想的な環境、分断と混乱の終了を得た上にさらに僕らのガバナンス、リリースプロセス、ワーキンググループを継続させることができる。あとは僕らが選択するだけだ。
まとめ
- Node.js と io.js の統合は最終局面へ
- 方針はio.js のガバナンス方針は踏襲される形で提案
- あとは僕らがどうあるべきかを選択するだけ
感想
元々 node-forward として始まった活動は、 Node.js を fork し、 io.js として進めた後にまた再び Node として戻ることになりました。
これこそが、 mikeal, Indutny を初めとして node-forward のメンバーがやりたかった事なので、僕としては反論は全くありません。
これまでの Node.js サイドから見れば、 Joyent だけの企業からのバックアップ体制だったのが、 IBM や Microsoftといった企業からも支援を受けて運用される形になります。コミュニティドリブンの体制なのは変更されません。
また、時を同じくして、 2014年からリーダーを務めていた TJ Fontaine がNodeのリーダーとJoyent社そのものから退くことになりました。
この話はまた次回のブログで。
io.js の v2.0 が出ました。
さてさて、久しぶりのio.js エントリですが、この度 io.js の v2.0 が出ました。
変更点をかいつまんで説明しましょう。書いてたら長くなってしまったので、サマリだけでいい人は最後のまとめを読むだけでいいと思います。
io.js は変化がものすごく激しく、v1.0 から v2.0 が入るまでに色んな機能が入っているんですが、知らない人も多いかと思います。
今回は v2.0 の単なる変更点だけじゃなくて、 v1.0 から今までで入った機能をサマリつつ伝えていこうかと思います。
Stream Simpler Construction (v1.2.0〜)
Stream の作成が簡単になりました。今までStreamを作るためには、目的のStreamを継承して、TransformStreamであれば _transform のようなメソッドを拡張して実現する必要がありました。
これをより簡単にしたものが through2 に代表されるヘルパライブラリでしたが、簡単にいえばこの through2 がなくても io.js では Stream を作るのが簡単にできるようになりました。
StreamのTransformに対して、transformやflushを取ることができ、これを使うとわざわざ継承をしなくてもTransform Streamを作ることが可能です。下記のようになりました。
before
var Transform = require('stream').Transform; var util = require('util'); util.inherits(MyTransform, Transform); function MyTransform(opts){ Transform.call(this, opts); } MyTransform.prototype._transform = function(chunk, encoding, callback){ // ここで 変換して ... // pushする this.push(chunk); }; MyTransform.prototype._flush = function(done){ // 最後に何かしたければここで flush する };
after
var transform = new stream.Transform({ transform: function(chunk, encoding, next) { // ここで 変換して ... // pushする this.push(chunk); }, flush: function(done) { // 最後に何かしたければここで flush する } });
ここでは Transform Stream で例を示しましたが、 Readable や Writable も簡単に作れるようになりました。
詳しくはコチラを見てください。
https://iojs.org/api/stream.html#stream_simplified_constructor_api
LTTNG サポート (v1.2.0〜)
HTTP のリクエストやサーバのレスポンス、GCの実行といった時にカーネルのレベルで何が起きているかを追うための機能が追加されています。今までの Node.js ではこれを行うのに Dtrace を使っていましたが、LinuxのDtrace実装は若く、全てが実装されているわけではありませんでした。結果として、 Joyentが提供している SmartOS等のSolarisをベースにしたUnix環境でしかNode.jsでDtraceを使うのはサポートされていませんでした。
これからは Linux カーネルでも標準でトレース可能な LTTNG も使えるようになりました。
詳しくはここを見てもらえるといいかと。
Promise の unhandledRejection / rejectionHandled イベント (v1.4.1〜)
Promise の catch を忘れた時に、 キャッチされていない例外として、 unhandledRejection と rejected 済みでもう呼ばれることがない例外を検出するための仕組みとして、 新しくrejectionHandledイベントが追加されました。
こちら、 azuさんの資料が詳しいので抜粋させてもらいます。
var bluebird = require("bluebird"); // unhandledRejection catchされていない例外 process.on("unhandledRejection", function (reason, promise) { console.log("unhandledRejection"); }); var resolved = bluebird.resolve(); resolved.then(function () { throw new Error("Yay!"); });
var Promise = require("bluebird"); process.on("rejectionHandled", function (promise) { console.log("rejectionHandled"); }); var rejected = Promise.reject(new Error("Error Promise")); setTimeout(function () { rejected.catch(function () { // rejected済みのpromiseに`catch`する }); },100);
Buffer に indexOf メソッドが追加されました。 (v1.5.0 〜)
Buffer に対して indexOf メソッドを使えるようになりました。これまでは 一旦 String にしたりしてから、中身の文字列を検索する必要がありましたが、その必要がなくなりました。
before
var fs = require('fs'); // ./foo.txt => yosuke furukawa fs.readFile(__dirname + '/foo.txt', function(err, buf){ var str = buf.toString(); console.log(str.indexOf('furukawa')); // 7 });
after
var fs = require('fs'); // ./foo.txt => yosuke furukawa fs.readFile(__dirname + '/foo.txt', function(err, buf){ console.log(buf.indexOf('furukawa')); // 7 });
詳しくはコチラ。
https://iojs.org/api/buffer.html#buffer_buf_indexof_value_byteoffset
node のコマンドに --require オプションで preload モジュールを渡せるようになりました。 (v1.6.0〜)
$ node --require ./a.js b.js
事前にpreloadしておきたい場合に使えます。
process.nextTick に複数の引数を渡せるようになりました。 (v1.8.0〜)
var obj = {}; process.nextTick(function(a, b) { assert.equal(a, 42); assert.equal(b, obj); }, 42, obj);
この変更によって、process.nextTick の callback に任意の引数を渡すことができるようになりました。
APIが setTimeoutやsetIntervalと似るようになりました。
REPL に history save 機能が追加 (v2.0〜)
REPL の magic mode と呼ばれる機能が追加されています。これは、環境引数NODE_REPL_HISTORY_FILE
を指定することでREPLを終了させても、次回の起動時に自分が実行したreplの内容を記憶してくれる機能です。いわゆる、 REPL の history save 機能ですね。
$ NODE_REPL_HISTORY_FILE=~/.node_history iojs > var fs = require('fs'); > fs.readFile; # Ctrl-D $ NODE_REPL_HISTORY_FILE=~/.node_history iojs > # push up button > fs.readFile;
これは NODE_REPL_HISTORY_FILEを指定しないといけなくて、必ず有効にはなりません。
僕は .zshrc
に以下のように書くことで対応しています。
# iojs alias iojs-repl="NODE_REPL_HISTORY_SIZE=Infinity NODE_REPL_HISTORY_FILE=~/.node_history iojs"
こうするとiojs-replで実行するときにはhistoryが有効になります。
ES6でデフォルトで使える構文が追加 (v2.0〜)
僕が少し前に作ったiojsの新機能紹介リポジトリにも書きましたが、日本語で説明を加えていきます。
class
クラスがデフォルトで使えるようになりました。
// strict mode needed 'use strict'; class Animal { constructor(name) { this.name = name } say() { // unimplemented } } class Cat extends Animal { say() { console.log(`${this.name} < meow`); } } var cat = new Cat('Mike'); cat.say(); // Mike < meow
これはかなり重要で、 io.js v2.0 を使っている分には util.inherits
のような継承のためのヘルパメソッドは不要になるし、ビルドインクラスを継承するのにも使えます。
enhanced object literals (v2.0〜)
Object のリテラルに拡張が加わりました。 以下のように key と value が一緒の時は省略して記述することができるようになります。
'use strict'; // class class Person { constructor(name, age) { this.name = name this.age = age } getInfo() { let name = this.name; let age = this.age; let nextAge = this.age + 1; // enhanced object literal return { name, age, nextAge }; } } var bob = new Person('bob', 15); console.log(bob.getInfo()); // { name: 'bob', age: 15, nextAge: 16 }
Rest パラメータが --harmony-rest-parameters オプション付きで有効になりました。
harmony option 付きで Rest パラメータが追加されました。
// Rest parameters function max(...args) { // rest parameter is not Array-like object, that is just array. console.log(Array.isArray(args)) // true console.log(args.length) // 6 var max = args.reduce(function(max, n) { return n > max ? n : max; }); return max; } var maxNum = max(5, 15, 10, 1, 4, 5); console.log(maxNum); // 15
実行するには下記のようにします。
$ iojs --harmony-rest-parameters es6/rest_params/rest.js
Computed property names が --harmony-computed-property-names オプション付きで有効になりました。
harmony オプション付きで、Computed property names が使えるようになりました。
var i = 0; var a = { ["foo" + ++i]: i, ["foo" + ++i]: i, ["foo" + ++i]: i }; console.log(a.foo1); // 1 console.log(a.foo2); // 2 console.log(a.foo3); // 3 var param = 'size'; var config = { [param]: 12, ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4 }; console.log(config);
以下のように実行します。
$ iojs --harmony-computed-property-names es6/computed_property/computedProps.js
Strong mode がサポートされました。 (v2.0〜)
今、 Google の v8 チームは色んな試みをしているのですが、 StrongScriptと呼ばれる試みをしています。
これは、JavaScriptの自由度の高い構文 (var, arguments, ==, delete, for-in 等)をなるべく deprecated にして、ES6 を含めた最新の構文(let, ...args, ===, Map, for-of)に書き換えるための試みです。
この StrongScript は コードの先頭に 'use strong' ディレクティブを付けることで Strong Mode になり、実行されます。
ちょうど 'use strict' で Strict Mode にするのと同様です。
今回のio.js v2.0 からこの Strong Mode が --strong_mode オプション付きで使えるようになりました。
※ ちなみにまだまだ実験的な試みなので、本番環境で使うのは推奨できません。
var => let/const
'use strong'; var a = 'hoge';
$ iojs --strong_mode strong_mode/vars.js /Users/yosuke/iojs_v2_features/strong_mode/vars.js:3 var a = 'hoge'; ^^^ SyntaxError: Please don't use 'var' in strong mode, use 'let' or 'const' instead at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:411:25) at Object.Module._extensions..js (module.js:446:10) at Module.load (module.js:353:32) at Function.Module._load (module.js:308:12) at Function.Module.runMain (module.js:469:10) at startup (node.js:124:18) at node.js:882:3
arguments => ...args
'use strong'; function some() { let args = Array.prototype.slice.call(arguments); } some();
$ iojs --strong_mode strong_mode/arguments.js /Users/yosuke/iojs_v2_features/strong_mode/arguments.js:4 let args = Array.prototype.slice.call(arguments); ^^^^^^^^^ SyntaxError: Please don't use 'arguments' in strong mode, use '...args' instead at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:411:25) at Object.Module._extensions..js (module.js:446:10) at Module.load (module.js:353:32) at Function.Module._load (module.js:308:12) at Function.Module.runMain (module.js:469:10) at startup (node.js:124:18) at node.js:882:3
eqeq => eqeqeq
'use strong'; if ('a' == 'a') { }
$ iojs --strong_mode strong_mode/eqeq.js /Users/yosuke/iojs_v2_features/strong_mode/eqeq.js:3 if ('a' == 'a') { ^^ SyntaxError: Please don't use '==' or '!=' in strong mode, use '===' or '!==' instead at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:411:25) at Object.Module._extensions..js (module.js:446:10) at Module.load (module.js:353:32) at Function.Module._load (module.js:308:12) at Function.Module.runMain (module.js:469:10) at startup (node.js:124:18) at node.js:882:3
propertyの削除に対して、 delete を使わず、 Map/Setを使う
'use strong'; let obj = { key: 'value'}; delete obj.key; console.log(obj);
$ iojs --strong_mode strong_mode/delete.js /Users/yosuke/iojs_v2_features/strong_mode/delete.js:5 delete obj.key; ^^^ SyntaxError: Please don't use 'delete' in strong mode, use maps or sets instead at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:411:25) at Object.Module._extensions..js (module.js:446:10) at Module.load (module.js:353:32) at Function.Module._load (module.js:308:12) at Function.Module.runMain (module.js:469:10) at startup (node.js:124:18) at node.js:882:3
for-in => for-of
'use strong'; for (let k in [1, 2, 3]) { console.log(k); }
$ iojs --strong_mode strong_mode/for.js /Users/yosuke/iojs_v2_features/strong_mode/for.js:3 for (let k in [1, 2, 3]) { ^^ SyntaxError: Please don't use 'for'-'in' loops in strong mode, use 'for'-'of' instead at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:411:25) at Object.Module._extensions..js (module.js:446:10) at Module.load (module.js:353:32) at Function.Module._load (module.js:308:12) at Function.Module.runMain (module.js:469:10) at startup (node.js:124:18) at node.js:882:3
幅広い環境のサポート (v1.4.0, v1.6.0, v1.8.0 )
今回、かなりビルド環境に気合が入っていて、幅広い環境でバイナリが提供されています。 Node.js の時は、 darwin(osx), linux, sunos(solaris), windows のバイナリが提供されるだけでしたが(それでもかなり素晴らしいけど)、 io.js からは ARM v6, v7も含めたかなり多くの環境でバイナリが提供されています。
binaryは提供されていませんが、 Android でも動くためのビルドオプションがあったり、SmartOS、FreeBSDでも動くためのオプションが提供されています。
また色んなOSの仮想環境を構築し、そこの上でテストを実行しています。どこかの環境でエラーがあったらすぐに分かるようになっています。
依存ライブラリ関連 (v2.0.0〜)
v8が 4.2 になった
v8が新しくなったので、JavaScriptの最適化やES6の機能が増えました。これに関しては先ほど紹介しました。
また、v8がアップグレードされたことで、V8のAPI が更新され、 Native Module も変更が必要になりました。
つまり、古いNative moduleのままでは動かなくなってしまいました。
現時点で v2.0 では動かないモジュール一覧に関しては以下のissueをご一読ください。
nan の更新を行うだけでいけるモジュールも多いので、忘れているモジュールに関しては、 今のところ nan を更新して pull request で教えてあげればいいかと思います。
ただ毎回 v8 が更新されるだけで動かなくなるモジュールがたくさんあると困るので、 nan を core に入れる提案もされています。
http-parser v2.5.0 になった
http-parserがやっと最新になりました。一旦 http-parser は v2.4になった後、バグが見つかりrevertされましたが、そのバグが修正され、高速化されたhttp-parserが使えるようになりました。
まとめ (v1.0 〜 v2.0の違い)
結び
さて、今回ざざっと v1.0 から今までの変更をお伝えしました。これらの変更は日本語の記事であれば、
にまとまっています*2。
変化の激しい io.js を追うのは大変ですが、この記事を毎週少しでも読んでおいてもらえると助けになると思います。
(毎週週末の時間を削って、翻訳している翻訳チームを助けてもらえるとありがたいです。)
また、コアチームは今は v3.0 に向けて動き出しています。僕もちょっとずつ改善を入れています。この変化を楽しみながら貢献できるといいなと思います。
Hexi というサイトを作りました (http2study で発表しました。)
Hexi というサイトを作ったので紹介です。
What is Hexi
Hexagonal Sticker as a Service と僕が勝手に呼んでいるものです。単純に六角形のステッカーを作って、公開して、購入できるECサービスです。
六角形のステッカーって実は標準規格があって、こんな感じになっています。
この標準規格に合わせて、これ専門のステッカー作れる所作って、勉強会とかで使ってもらったら便利じゃね?と思ったので、友人の会社(絶賛エンジニア募集中)に持ちかけて、自分もバックエンドを基本に空き時間で手伝いながら作りました。
Hexi inside
割りと基本は抑えつつも突っ走った構成をしていて、
- nginx (with SPDY)
- ngx_small_light (画像リサイズ)
- io.js (v1.6.4 express)
- Amazon S3, RDS
っていう感じになっています。今回画像などのassetsが割りとたくさん存在するのでSPDYはかなり効果を発揮していて、なにもない時と比較して、200 〜 300 ms 位の差を出しています。
また、今回僕がインフラとバックエンドに徹したので、フロントのJavaScriptをconcatしたり、cssをconcatしたりっていう所謂フロントエンドタスクに手が回らなかったんですが、それも功を奏していて、SPDYであれば理論上はconcatしなくてもそれと同等の性能が得られる上に、むしろconcatして余分なJSやcssが入るよりも性能の向上が期待できるようになりました。
uglifyだけは都合上やってもらいましたが、それ以外のタスクはほとんどやっていません。
そこまでインフラにお金はかけられなかったので、最小のEC2一つだけで色々やってます。EC2一個にしては割といいパフォーマンスが出ているかなと思っています。
あと、僕が io.js の collaborator 兼 evangelist としてio.jsを採用したので、バグを踏んでは io.js へのコントリビュートという一石二鳥を積極的に狙ってやれました。(こうすることで、io.js側のバグ修正もある程度充実させることができました :D )
Hexi の反響
まず、 hexb.in っていう @maxogden がやってる六角形ステッカーのサイトに公式の販売ベンダーとして名前が載りました。
NodeSchool の @finnp っていうオーガナイザーの一人からベルリンにもステッカー送ってほしいって言ってもらってすごく嬉しかった。github.com
TokyoJSのオーガナイザーからも買いたいっていう問い合わせがあって、色々と作ってよかったなという所感です。
これ作りたいな〜 http://t.co/UkAsmP1zW0 #Hexi via @hexi_pr
— Tokyo JS (@tokyo_js) 2015, 4月 19
あと、デザイナーさん達が作ってくれるステッカーに可愛いのが多いです。
Hexi future
一応、今後は http2 にしたり、 ngx_small_light やめて AWS Lambda で事前リサイズしたりともう少しアーキテクチャは洗練していく予定です。
そろそろ出るという噂の io.js v2.0 にもする予定です。
Hexi 発表資料 (in http2study)
ES6 を学べる tower-of-babel を作りました。 (workshopper の作り方)
さて、NodeSchool が開校された時に、ES6を学べるチュートリアル的なものがほしいと思い、tower-of-babelという名前のチュートリアルツールを作成しました。
このツールはnpm/node.jsを使って作っています。実際に動かすときはnpmがあれば動きます。
npmのインストールは他の記事を参考にしてください。npmが入っていれば、以下のようにすれば実行可能です。
$ npm install tower-of-babel -g $ tower-of-babel
そうすると下記のようなダイアログが起動するのでエクササイズを選択して各種問題を解いてください。
全ての問題を解き終わった頃にはなんとなく ES6 の構文が使いたくなってくるはずです。
なにか問題があれば気軽に tower-of-babel のリポジトリに連絡をください。
以下の話はworkshopperを作ってみたい方限定です。
workshopperの作り方
さて、NodeSchoolが如何に素晴らしいか、如何に初心者のNode.jsを押し上げるのに一役買っているかは前回の記事で軽く触れましたが、同じカリキュラムしか存在しないと受講生のみんなは飽きてきます。
今でもNodeSchoolには素晴らしいカリキュラムが数多く存在しますが、自分達から率先して新しいカリキュラムを作るのも良いと思います。
今回はそんな形で新しいカリキュラムを作るのにどうやって作ったらいいのか、 解説します。
今回のブログを読めば大体みんな作れるようになるかと思います。
workshopper / workshopper-exercise のインストール
適当なプロジェクト名のフォルダを作り、 npm init で package.json のひな形を作っておいてください。
$ npm init $ npm i workshopper workshopper-exercise -S
workshopper の実体はあのファンシーなターミナルメニューを持つテストランナーです。
workshopper-exercise はテストランナーに対する validator、つまりアサーション機能の役割を果たしています。
最近では workshopperをさらに機能拡充した workshopper-adventure があります。これはworkshopper 新バージョンのβ版的な位置づけで色々便利な機能があります。大阪NodeSchoolのオーガナイザーである マーティンが作っています。
workshopper の定義を行う
プロジェクトフォルダの適当なファイルを作ってそのファイルを実行できるようにします。
tower-of-babelの場合は、 プロジェクトフォルダのルートに `tower-of-babel.js` を作ってそこに定義を書きました。
#!/usr/bin/env node const workshopper = require('workshopper-adventure'); const path = require('path'); function fpath (f) { return path.join(__dirname, f) } workshopper({ name : 'tower-of-babel', title : 'Tower of Babel', subtitle : 'Learn ES6 features using babel', appDir : __dirname, menuItems : [], languages : ['ja'], exerciseDir : fpath('./exercises/') })
こんな感じ。
エクササイズを作っていく
ここまで行くと後はエクササイズを作っていくまでです。
exercises フォルダを作成し、その中に menu.json を作りましょう。
[ "BABEL SETUP", "CLASS", "CLASS EXTEND", "MODULES WITH NAME", "MODULES DEFAULT EXPORT", "BLOCK SCOPE", "COMPUTED PROPERTY", "ITERATOR FOR OF", "GENERATOR", "DESTRUCTURE", "ARROW FUNCTION", "REST AND SPREAD" ]
このmenu.jsonの配列の要素一つ一つがエクササイズになります。このエクササイズのフォルダを作成します。
フォルダを一個一個作成してもいいんですが、以下のコマンドを実行すると勝手にスケルトンが作られて便利です。
$ node_modules/workshopper/util/makews.js exercises/menu.json
exercises ├── arrow_function │ ├── exercise.js │ ├── problem.ko.md │ ├── problem.md │ └── solution │ └── solution.js ├── babel-processor.js ├── babel_setup │ ├── exercise.js │ ├── problem.ko.md │ ├── problem.md │ └── solution │ └── solution.js ├── block_scope │ ├── exercise.js │ ├── problem.ko.md │ ├── problem.md │ └── solution │ └── solution.js ├── class │ ├── exercise.js │ ├── problem.ko.md │ ├── problem.md │ └── solution │ └── solution.js ├── class_extend │ ├── exercise.js │ ├── problem.ko.md │ ├── problem.md │ └── solution │ └── solution.js ├── computed_property │ ├── exercise.js │ ├── problem.ko.md │ ├── problem.md │ └── solution │ └── solution.js ・・・
exercise.js
にexerciseをrun, verifyした時の検証の方法を記述します。
problem.md
に 問題文そのものを記述します。markdownで書けます。
solution/solution.js
に回答のJavaScriptを記述します。
実際の例を上げるとこんな感じです。
block scopeの問題の例
exercise APIを覚える
tower-of-babelで利用しているexerciseは全て同じ作りをしていて、原理から説明すると、受講生が記述するファイルとsolution.jsをbabelでtranspileした後、child_processを使って実行し、標準出力の結果が同じかどうかをチェックします。
中の構造が同じかどうかまではチェックしておらず、同じ出力結果が出ること、期待しているキーワードを使っていることしかチェックしていません。
tower-of-babelで使っているのは以下のAPIです。
- filecheck API (指定されたファイルが存在するかチェックするAPI)
- execute API (child_processを使ってファイルを実行するAPI)
- comparestdout API (標準出力結果をチェックするAPI)
使い方はこの辺を見てください。
tower-of-babel/exercise.js at master · yosuke-furukawa/tower-of-babel · GitHub
まとめ
tower-of-babelを作って、公開しました。ES6を学びたい皆様、ぜひぜひやってみてください。
あと、 5/23 (土) にもまた NodeSchool International Day でこれを学べるようにしようと思います!!
ちなみに、tako-blackさんが learnyoureact っていうreact 学習用のツールを作ってくれました。
こちらもNodeSchool International Day で出る予定です。