NodeConf Adventure 2015 に行ってきました。(一日目、二日目に起きたこと)

NodeConf に行ってきました。 NodeConf っていうのは Node.js のための勉強会です。 io.js の中心人物である mikeal や、 npm のCEO である izaacs 、 hapijs author であり、先日 Walmart を退社した Eran Hammer など、そうそうたるメンバーの中でディスカッションをしてきました。

NodeConf Adventure とは

NodeConf Adventureはいわゆる発表者がいて、聴講者が聞くっていうスタイルのカンファレンスじゃありません。

なんというかものすごくメタなカンファレンスで、ワークショップとノウハウの共有をメインとしたディスカッションのための場所です。 アンカンファレンスっていう形式ですね。

午前中に主催者である mikeal がロッジに全員を集合させます。
その後で参加者全員に何が聞きたいかを決めてスタート。

みんな isomorphic とか ES6 とか IoT とか microservices とか言って、発言していて、 substack が 「P2P hack しようぜ」って言ってたのが面白かった。( mikeal は興味なかったみたいでスルーされてたけど。)

それぞれのトピックごとに場所を分けてスタート。

isomorphic

isomorphic って言ってもメインは サーバサイドレンダリングと React っていうよくある話だった。やっぱり viewの機能をサーバサイドで使えるようになったこと、初期表示のスピードが通常のSPAより改善できること、SEOによるアクセス向上などの話がメイントピックだった。

面白かったのは、 browser で module の解決とかどうするのかっていう話で browserify から ES6 に話は飛び火して、 isomorphic を実現するための鍵としてやっぱり ES6 module なんじゃないかっていう話が一番面白かった。

今は browserify っていうか commonjs が主流だけど、これをどうするのか、あと HTTP/2 とかが来たらどうなるのかっていう議論をしていた。(もっと英語で話せるなら日本だとこういう議論してるって言えたんだろうけど、議論に割り込む勇気がなかった)

あと、ここでも fluxible 使ってるっていう人とか meteor で頑張ってるっていう人もいたけど、一人自作したっていう人が居てその人の lighter っていうライブラリを教えてもらってた。

Lighter.io - faster is better

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 とは同じ部屋であることもあってすごく仲良くなった。

https://cldup.com/n_70N0wE5r.jpg

Oliver とパシャリ

Node Stability の話

Node.js の安定性っていう io.js Collaborator としてものすごく興味深いトピックに対しての議論だった。



izaacs とか mikeal とか Fishrock とか Chris Dickenson とかのこれまでのコラボレーター達が今後どうするべきかについて議論してた。

最終的に議論の成果として、現時点で mikeal が思うバージョン階層について説明してくれた。

これを io.js の issue に上げて今でも議論中。

f:id:yosuke_furukawa:20150623022328p:plain

こんな感じになる予定らしい。

ES6/7 の話

みんな ES6/7 の関心が高いようで、やっぱりここでも babel の存在感は大きかった。

特に議論になっていたのは、 async-awaitの話、decorator の話、function-bind の話で、みんな ES7 の話をしていた。

特に、 async-await と generator-yield の使い分けの話がメインだった。
NodeConfだとまだ async-await を使って ES7 やるぜっていう人はそこまで多くなかったけど、 io.js だと generator-yield がネイティブに使えるのでそれを基本にやってる人はまぁまぁ多かった。

ES6 workshop

ES6 を io.js を使って動かしてみようワークショップ、これも Oliver さんが担当。

github.com

これ実は微妙に手伝ってて、このリポジトリに io.js の ES6 の issue 投げてたり、 Oliver と discussion してたら、何かわからないことあったらフォローしてくれと言われたので、注意深く聞いてた。

これに関しては知っている事も多かったので、時折Oliverを補足したりしながら進めることができた。

Interview with Chris and Fishrock

終わった後で、 io.js の TC member であるChris DickensonFishrock123 と一緒に今後の 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 はちょい堅物の若者っていう感じだった。

f:id:yosuke_furukawa:20150622030920p:plain
Chris とパチリ(Fishrock 帰り際に捕まえられなかった、でも良い奴だった)

レクリエーション

夕飯を食べていたら急に MaxOgden と substack が「お前ら!ゲームやるぞ!!」って言い出したので参加してきた。

まとめ

  • isomorphic で fluxible が人気、 meteor も使ってる人多かった
  • ES6へのみんなの関心は ES7 に移ってた
  • Node Stablity という事で安定バージョンをどうやって提供するか提案された
  • isomorphism の話を Fishrock, Chris として何となく彼らが思っている事がわかった
  • レクリエーションゲームで勝利!!

続きは三日目と四日目に起きたことを書くよー!

YAPC で Node.js のトークに応募しました。

Node.js 日本ユーザーグループ代表の古川です。

YAPC でまだ話せるのかは分からないのですが、せっかくなので宣伝させてください。
YAPC というイベントでトーク応募しました。

yapcasia.org

Node.js と io.js の話はこのブログでずっと話してきたんですが、ある程度まとまってきた所で振り返って話をしようかなと思っています。 日本ユーザーグループ代表の僕と 先日 io.js の技術委員会にノミネートされた 大津さん (@jovi0608) とでこれまでの Node.js の話と io.js の fork 騒動、 そして今後の Node.js という流れで話そうと思っています。

細かい部分は決めていませんが、これまでの流れをおさらいしつつ、最後は二人でパネルディスカッション形式で話しつつ、会場からも広く質問を受け付けるような形で進行できるといいかなと思っています。

聞いてみたいという方がいたらTwitterFacebookはてなブックマークなど、何でも良いので押してください。何卒よろしくお願いいたします。 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っていうカンファレンスがあるんでそこで話を聞いてきます。

NodeConf 2015

向こうではワークショップも多くて、 isomorphic の web application を学べるワークショップがあったり、 ES6 のワークショップがあったりと楽しそうなので、面白そうな話があれば展開することも忘れずに行ってきます。

github.com

github.com

最後に

何卒、トークの応援の程よろしくお願いいたします。

yapcasia.org

Node.js と io.js の統合は最終局面へ

いくつかこの何日間でニュースが出ているので紹介します。

ちなみに、 io.js と Node.js のニュースに関してはこれまで2つ書いたので、まだ良く知らない人はそれをまずはご一読ください。

yosuke-furukawa.hatenablog.com

yosuke-furukawa.hatenablog.com

さて、次の展開へ、という事でいくつか話があります。

「Join the Node Foundation?」 というissueが mikeal から提案される

github.com

issue 本文を翻訳したものを貼っておきます。

Node Foundationのためのすべての文書が揃った。

gistの内容はつまり、「Node Foundationのガバナンス構造は io.js のガバナンスとほぼ一致している」という事を示している。実際、全ての文書を記述している最中に我々のポリシーを盛り込むために文書を改善させたし、より良い文章が作られていった。新しく "統合された" node プロジェクトは初期リリースターゲットとして、io.js master に入っているものをベースに、node.js からの変更はポーティングされてリリースされることになるだろう。


我々にはfoundationが必要であると私は思っているし、Linux Foundation は Node Foundation を基準とした構造として理想だ思っている。その理由はここに書いた。

medium.com

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の中であった反対意見を上げると:

  1. オープンガバナンスモデルのLive Stream配信がされなくなるのは困る(GoToMeetingはアーカイブ配信しかしない)
  2. 先に参加を表明して、後からコードをマージするのは問題が起きる可能性がある。変更がfixされてから(node.jsチームが変更をもう追加しないという状態になってから)参加するようにしないと後から彼らにとって都合の良い変更が勝手に加わる可能性がある。
  3. 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 に読み替えておいてください。)

f:id:yosuke_furukawa:20150512040315p:plain

次の新しいnodeの名前はどうなるの?

元のNode.jsに戻ると思います。ただそうなると、Twitter IDとかlogoとかwebsiteのドメインとか作り直しに近いので、まぁそうなったらそうなったでしょうがない感じはしますね。今丁度 Website WGでは new.nodejs.org みたいな話でドメイン名の検討も含めて議論中です。

今のコアメンバーの思いは?

そこまで意思を全員が表明しているわけじゃないですが、基本的には統合に向いています。ちょうどこの調整に対しての一番の功労者である、 mikeal はブログの中で以下のように述べています。

medium.com

僕達には 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 だけの企業からのバックアップ体制だったのが、 IBMMicrosoftといった企業からも支援を受けて運用される形になります。コミュニティドリブンの体制なのは変更されません。

また、時を同じくして、 2014年からリーダーを務めていた TJ Fontaine がNodeのリーダーとJoyent社そのものから退くことになりました
この話はまた次回のブログで。

io.js の v2.0 が出ました。

https://hexi.pics/resize/w/462/h/462/e03baa40377a8e562cb376199c6e3721.png


さてさて、久しぶりの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 も使えるようになりました。
詳しくはここを見てもらえるといいかと。

Node LTTNG

http://nearform.github.io/tracing-node-lttng-nodejsdublin/pictures/demo.gif

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);

Promise Error Handling

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が有効になります。

詳しくはコチラ
https://iojs.org/api/repl.html#repl_repl

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の仮想環境を構築し、そこの上でテストを実行しています。どこかの環境でエラーがあったらすぐに分かるようになっています。

https://jenkins-iojs.nodesource.com/job/iojs+any-pr+multi/

依存ライブラリ関連 (v2.0.0〜)

v8が 4.2 になった

v8が新しくなったので、JavaScriptの最適化やES6の機能が増えました。これに関しては先ほど紹介しました。
また、v8がアップグレードされたことで、V8のAPI が更新され、 Native Module も変更が必要になりました。
つまり、古いNative moduleのままでは動かなくなってしまいました。

現時点で v2.0 では動かないモジュール一覧に関しては以下のissueをご一読ください。

github.com

nan更新を行うだけでいけるモジュールも多いので、忘れているモジュールに関しては、 今のところ nan を更新して pull request で教えてあげればいいかと思います。
ただ毎回 v8 が更新されるだけで動かなくなるモジュールがたくさんあると困るので、 nan を core に入れる提案もされています。

OpenSSL v1.0.2a になった

OpenSSL が v1.0.2a になり、 crypto の性能が改善されました。
この辺りの記事が詳しいです。*1

github.com

http-parser v2.5.0 になった

http-parserがやっと最新になりました。一旦 http-parser は v2.4になった後、バグが見つかりrevertされましたが、そのバグが修正され、高速化されたhttp-parserが使えるようになりました。

libuv が v1.4.2 になった

libuv が新しくなりました。 windows/linuxでのバグ修正や ARM でも動くようにするための修正などが含まれています。

npm が v2.9.0 になった

npm も新しくなりました。翻訳があるのでそこを見ておくと良いかもしれません。

medium.com


まとめ (v1.0 〜 v2.0の違い)

  • Streamを簡単に作れるようになった
  • LTTNG のサポート
  • Promise の unhandledRejection / rejectionHandled イベント
  • Buffer の indexOf メソッドを追加
  • node --require オプション追加
  • repl に history をsaveするモードが追加
  • v8 が新しくなり、 class, object リテラルの拡張 etcとStrong Mode が追加
  • ARMを初めとする バイナリの提供と幅広い環境のサポート
  • 依存ライブラリの刷新による性能向上、バグ修正など

結び

さて、今回ざざっと v1.0 から今までの変更をお伝えしました。これらの変更は日本語の記事であれば、

blog.iojs.jp

にまとまっています*2

変化の激しい io.js を追うのは大変ですが、この記事を毎週少しでも読んでおいてもらえると助けになると思います。
(毎週週末の時間を削って、翻訳している翻訳チームを助けてもらえるとありがたいです。)

また、コアチームは今は v3.0 に向けて動き出しています。僕もちょっとずつ改善を入れています。この変化を楽しみながら貢献できるといいなと思います。

*1:大津さんが書いてくれました。 大津さん ++

*2:いつも翻訳してくれる @watilde さん、 @jgs さん、 @kosamari さんに感謝です。

Hexi というサイトを作りました (http2study で発表しました。)

hexi.pics

https://cloud.githubusercontent.com/assets/555645/7000462/609930fa-dc5e-11e4-8b29-f28545846d14.png


Hexi というサイトを作ったので紹介です。

What is Hexi

Hexagonal Sticker as a Service と僕が勝手に呼んでいるものです。単純に六角形のステッカーを作って、公開して、購入できるECサービスです。
六角形のステッカーって実は標準規格があって、こんな感じになっています。

Stickers Standard


この標準規格に合わせて、これ専門のステッカー作れる所作って、勉強会とかで使ってもらったら便利じゃね?と思ったので、友人の会社(絶賛エンジニア募集中)に持ちかけて、自分もバックエンドを基本に空き時間で手伝いながら作りました。

Hexi inside

割りと基本は抑えつつも突っ走った構成をしていて、

  • nginx (with SPDY)
  • ngx_small_light (画像リサイズ)
  • io.js (v1.6.4 express)
  • Amazon S3, RDS

f:id:yosuke_furukawa:20150430033203p:plain

っていう感じになっています。今回画像などのassetsが割りとたくさん存在するのでSPDYはかなり効果を発揮していて、なにもない時と比較して、200 〜 300 ms 位の差を出しています。

また、今回僕がインフラとバックエンドに徹したので、フロントのJavaScriptをconcatしたり、cssをconcatしたりっていう所謂フロントエンドタスクに手が回らなかったんですが、それも功を奏していて、SPDYであれば理論上はconcatしなくてもそれと同等の性能が得られる上に、むしろconcatして余分なJSやcssが入るよりも性能の向上が期待できるようになりました。

uglifyだけは都合上やってもらいましたが、それ以外のタスクはほとんどやっていません。

f:id:yosuke_furukawa:20150430033606p:plain

そこまでインフラにお金はかけられなかったので、最小のEC2一つだけで色々やってます。EC2一個にしては割といいパフォーマンスが出ているかなと思っています。

あと、僕が io.js の collaborator 兼 evangelist としてio.jsを採用したので、バグを踏んでは io.js へのコントリビュートという一石二鳥を積極的に狙ってやれました。(こうすることで、io.js側のバグ修正もある程度充実させることができました :D )

Hexi の反響

まず、 hexb.in っていう @maxogden がやってる六角形ステッカーのサイトに公式の販売ベンダーとして名前が載りました

NodeSchool の @finnp っていうオーガナイザーの一人からベルリンにもステッカー送ってほしいって言ってもらってすごく嬉しかった。github.com

TokyoJSのオーガナイザーからも買いたいっていう問い合わせがあって、色々と作ってよかったなという所感です。

あと、デザイナーさん達が作ってくれるステッカーに可愛いのが多いです。

hexi.pics
hexi.pics
hexi.pics

Hexi future

一応、今後は http2 にしたり、 ngx_small_light やめて AWS Lambda で事前リサイズしたりともう少しアーキテクチャは洗練していく予定です。
そろそろ出るという噂の io.js v2.0 にもする予定です。

f:id:yosuke_furukawa:20150430040130p:plain

Hexi 発表資料 (in http2study)

http2study.connpass.com

ES6 を学べる tower-of-babel を作りました。 (workshopper の作り方)

さて、NodeSchool が開校された時に、ES6を学べるチュートリアル的なものがほしいと思い、tower-of-babelという名前のチュートリアルツールを作成しました。

github.com


このツールはnpm/node.jsを使って作っています。実際に動かすときはnpmがあれば動きます。
npmのインストールは他の記事を参考にしてください。npmが入っていれば、以下のようにすれば実行可能です。

$ npm install tower-of-babel -g
$ tower-of-babel

そうすると下記のようなダイアログが起動するのでエクササイズを選択して各種問題を解いてください。
全ての問題を解き終わった頃にはなんとなく ES6 の構文が使いたくなってくるはずです。

https://cloud.githubusercontent.com/assets/555645/6997242/a65df93c-dbef-11e4-9bf8-f39331c56d1f.png

なにか問題があれば気軽に tower-of-babel のリポジトリに連絡をください。

github.com

以下の話は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.js
problem.md
solution.js

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 で出る予定です。

NodeSchool Tokyo を開催しました

f:id:yosuke_furukawa:20150412165718j:plain

NodeSchool Tokyo を開催しました。かなり面白かったのでその様子をちょっとでもお伝えできればと思います。

NodeSchoolとは

JavaScript に関する授業を集めた学校です。みんなでコードを書いたり、問題を解いたりすることで勉強できるようになっています。

今回は初回だったので、いくつか失敗した点もあったのですが、Node.jsを初めて触った人でも asyn i/o に触れたり、 babelで ES6 を学んだりと多岐に渡るカリキュラムを実施することができました。

nodejs.connpass.com

https://hexi.pics/resize/w/462/h/462/0f48f67359995f579a3a03da77320fe5.png

どんな感じでワークショップをするのか

npm のモジュールをインストールしてもらって、そのCLIツールを元に実施します。
workshopperというCLIツールを使います。npmが動く環境さえあれば実行できるため、講師が一つ一つ説明しなくても実行できるようになっています。

# learnyounode と呼ばれるカリキュラムを開始する
$ npm install learnyounode -g
# learnyounodeを起動
$ learnyounode

https://camo.githubusercontent.com/17955d1d684a9a0b3fd9d5d863393e6e952cc3b4/68747470733a2f2f7261772e6769746875622e636f6d2f72766167672f6c6561726e796f756e6f64652f6d61737465722f6c6561726e796f756e6f64652e706e67

今回実施したカリキュラム

会場でアンケートした結果、大体 7割くらいの人が learnyounode に取り組んでもらっていて、残りの1割を他の how-to-npm, javascripting, tower-of-babel が分け合う感じでした。みんな node.js に興味があるんだなとしみじみ。

f:id:yosuke_furukawa:20150412150024j:plain

大体早い人でも2時間くらいかかるカリキュラムなので、この時間内で全部終わった人は少なかったんですが、 コツを掴むのがうまい人は2つくらいのカリキュラムに取り組んでいて素晴らしかったです。

tower-of-babelは僕が作ったworkshopperで、割と沢山の人達から実施してもらいました。

英語化への翻訳も進んでいるので、英語化が済んだらまた広く公開していこうと思います。

LT大会

Node.jsで対戦ゲームを作った話 by yuusuke_takeuchi_96

Node.jsで対戦ゲームを作ったという話、socket.ioを使ったら簡単にゲームが作れるという話で、NodeSchoolっぽく初心者にも優しいデモになっていました。

画像変換サーバをNode.jsで作った話 by bojovs

Tomboと呼ばれる画像リサイズサーバーを作った話、koaを使っていたりとだいぶモダンな構成で素晴らしかった!僕らも最近リサイズサーバーをngx_small_lightでやっていたが切り替える可能性はありますね。

LoopBackを使った極初歩的なAPISwiftで作るオシャレアプリ()by isamu_suzuki_54

Swift でろうそくに対して吹き込むと風を送ってゆらぎ効果を出せるアプリを作ってくれました。
このアプリのAPIはLoopBackで作っているらしく、しかも2014年のNode学園祭の時のIssac Rothさんの話を聞いて、使ってみたくなったということで、主催の立場からするとすごく嬉しかった!!

こわくない!ディレクターがexpressではじめる新規開発 by hiro93n

ディレクターがexpressを学び始めてからちゃんと書けるようになるまでの軌跡を示してくれました。
ちなみに、僕と一緒に hexi を作っている人です。hexiについてはまた今度詳しく紹介します。

hexi.pics

まとめと今後

こんな感じでした。すごく面白かったと言ってくれる人が多くて良かったです。メンター側も色々と教える行為を通してレベルを上げられたのではないかと思います。

NodeSchoolはこんな感じで初心者向けですが、ある程度知っている人はメンターとして参加する、workshopperを新しく作るなどで貢献することも可能です :D

ちなみに今回は参加特典として ハチ公の六角形ステッカーとtower-of-babelやってくれた人用に babel ステッカーを用意しました。

hexi.pics
hexi.pics

みんながmacに付けてくれてるのを見て嬉しかった。

次の NodeSchool は 5/23(土) に開催予定です!また東京でやる予定なので是非参加してください。

https://hexi.pics/resize/w/462/h/462/da2efdeea09abcdd601d1d3ab99be13d.png