Experts.jp日本に、もっとエキスパートを。v4がリリースされました。v0.12やv0.10と比較してどう違うのかを解説します。最新ではv5もリリースされていますので、合わせてお伝えしていきます。なんでいきなりv4なのかおそらく一番最初に抱く感想は、v0.10とかv0.12みたいな数字からv1.0を飛ばして、なんでいきなりv4.0がリリースされたのかという疑問だと思います。これにはio.jsというプロダクトが関係しています。2014年の年末、io.jsというプロダクトが発表され、2015年の初めにv1.0がリリースされました。forkで別リポジトリによって実装されたプロダクトです。io.jsの詳細は筆者のブログを確認してください。io.jsがリリースされた後、週次リリースという早いサイクルでリリースするモデルを確立し、8カ月間もの間リリースを続けてきました。結果として、io.jsはv3までリリースされています。紆余曲折を経た後に、Node.jsはこのio.jsと再び統合されることになります。統合までの経緯について、興味がある読者の方は筆者のYAPCでの発表資料を参考にしてください。統合される際にio.jsの既存バージョンと競合しないようにした結果、Node.jsはv1.0からv3.0を飛ばしていきなりv4.0がリリースされることになりました。v3が元になっています。v4では利用可能です。v4で入った新機能や違いを解説します。v5で入った機能は本資料の最後にまとめて紹介します。v4は内部的にJavaScript実行エンジンである、V8のv4.5を採用しています。これにより下記の部分でJavaScript全体の機能が進化しました。一つ一つ説明していきます。v0.12と比較して拡大しました。具体的には下記の機能がデフォルトで有効になっています。StringリテラルString.prototype.repeatSymbol.toStringTag拡張ObjectリテラルUnicodeリテラルアロー関数ES2015の構文のサポート範囲が変わったことで今までNode.jsで記述していたJavaScriptは変わっていくだろうと予測されます。具体的にどのように変わるのか、EventEmitterを拡張してMyEventEmitterを作るというケースを参考に考えてみましょう。v0.12まではEventEmitterを拡張する場合、以下のように記述していました。MyEventEmitter;このMyEventEmitterは、intervalCheckという内部的にdataが変わっていないかどうかを1秒ずつ調べて変更があったら、changeイベントを発火させるという動きを行っています。v4からは下記のようにES2015の構文を使って下記のように記述します。アロー関数を利用する。アロー関数を利用する。MyEventEmitter;ひとつ前のコードと比較すると大分コードが短く、シンプルに記述できるようになっていることがわかります。callやnew.targetなどの新しい機能も使えるようになっています。現時点ではまだ下記のような機能は有効になっていません。optimizationProxy/ReflectmodulesStrongScript等のJavaScriptの新機能対応StrongScriptというのはES2015のコードを強制させ、JavaScriptの実行エンジンにとって親和性の高いコードを生成するための新しい試みです。strictをつけることで厳格モードというモードになりますが、この厳格モードをより強くしたモードです。向上という2つの事を狙った試みであり、特にpredictabilityが上がることでJavaScriptの実行エンジンフレンドリーになり、全体的に性能が上がる事が期待されます。//下記のコードは、StrongModeでは全てエラーになります。varを利用する代わりにlet、もしくはconstを使いましょう。置くけど、空の式を置くのは間違いの元なのでやめましょう。for-inの代わりに、for-ofを使いましょう。delete構文を使うなら、Map/Setを代わりに使いましょう。いう名前の変数に何かを入れるのはやめましょう。未定義のプロパティに、勝手にアサインするのはやめましょう。{//下記のコードは、StrongModeでは全てエラーになります。varを利用する代わりにlet、もしくはconstを使いましょう。置くけど、空の式を置くのは間違いの元なのでやめましょう。for-inの代わりに、for-ofを使いましょう。delete構文を使うなら、Map/Setを代わりに使いましょう。いう名前の変数に何かを入れるのはやめましょう。未定義のプロパティに、勝手にアサインするのはやめましょう。strong"ディレクティブを書くだけじゃなく、実行時のオプションとして--strong_modeオプションが必要です。weak.jsStrongScriptの詳細については、以前まとめた資料があるのでご一読ください。StrongScriptについてIntlオブジェクトのサポートによる国際化対応ECMAScript国際対応用のAPIが利用できるようになっています。ECMA-402と呼ばれる仕様で通称ESIntlと呼ばれています。これを利用することで例えば時刻表期の国際化対応や通貨表記の国際化対応ができるようになります。デフォルトでは利用できないので、ビルドするときにオプションを指定する必要があります。下記のようにオプションを指定して実行すると有効になります。installこれを使うと新たにIntlというbuilt-inオブジェクトがglobal空間に生成されて使えるようになります。文字列比較処理から見ていきましょう。文字列比較をする際に日本語にはカタカナやひらがなといった表記の違いとまた句読点といった区切りが存在します。読みやすくするためには表記の違いを使い分けたり、句読点をしかるべき所に入れる必要がありますが、プログラミングで文字列をソートしたり、検索するときなどはこれらの区別が不要なときも多いです。いう場合に利用するのがIntl.Collatorというクラスです。利用方法は以下のとおり。文字の派生系を同値と見なします、カタカナとひらがなの区別もつけません。文字で発音が同じものを同値と見なします。baseの中で派生系は不等という指定です。文字の派生系を同値と見なします、カタカナとひらがなの区別もつけません。文字で発音が同じものを同値と見なします。baseの中で派生系は不等という指定です。同値また、この他にも時刻表記(Intl.DateTimeFormat)や通貨表記(Intl.Numberformat)といった数字の表記を、国際化対応することが可能です。v4では、JavaScriptの文法部分での進化と内部でのリファクタリングは進んでいるものの、APIとして新しい機能はそこまで増えていません。追加された機能はいくつかありますが、主だったものとしては下記の通りです。一つ一つ説明していきます。変更Node.jsには、Bufferと呼ばれるbinaryデータを扱うためのAPIが存在します。普通にNode.jsのライブラリを利用するときにはあまり意識していないかもしれませんが、fsからreadFileした時の戻り値やhttpのPOSTメッセージを受け取った時は基本的にBuffer型の値を受け取っています。JavaScriptにはArrayBufferという似たオブジェクトが存在しますが、v4.0.0からはこのArrayBufferをBufferが継承する形になりました。これによってArrayBufferで利用可能なAPIはBufferでも利用可能になります。それとは別にBufferにindexOfメソッドが増えました。これによりわざわざ文字列に変換しなくてもBufferとしてそのまま文字列を含んでいるかどうかを検索することができるようになります。7});これまではindexOfなどの文字列検索をする場合、一旦toStringを使って文字列を変換する必要がありました。これはNode.js内部では、Buffer型からstring型への変換をしている上にさらにHeapメモリを消費してしまうため、メモリ効率的にも速度効率的にも悪いというデメリットが有りました。今回のv4.0からはindexOfメソッドがBufferで利用可能になっているため、このデメリットを解消しています。内部的にもこのメソッドを利用することで速度の向上が見られます。ArrayBufferで再実装された影響で以下のようなArrayBufferをそのままコンストラクタに入れられるようになりました。追加Streamの作成が簡単になりました。_transformのようなメソッドを拡張して実現する必要がありました。v4.0ではStreamを作るのが簡単にできるようになりました。最後に何かしたければここでflushする}});詳しくはこちらのAPI資料を参考にしてください。os.homedir機能の追加HOMEディレクトリを取得するための関数os.homedirが追加されました。/User/yosuke今まではHOMEの環境変数から取得したり色々な方法で解決していましたが、これからはos.homedir関数で取得することができます。性能向上v8のバージョンアップ、http_parserモジュールのバージョンアップにより、これまでよりも性能が8%ほど向上しています。前述したBufferの改善により、メモリ効率的にも向上が見られます。この結果を見ていただくと分かる通り、Requests/secondベースでhttpの速度が8%程改善されています。こちらの結果では、性能改善はもとより、メモリ効率的にも効率化されていることがわかります。httpだけではなく、fsにwritev書き込みをするモードが追加されたり、require関数の無駄な処理を省いて高速化するといったことが行われています。なったAPI残念ながら、deprecatedになったAPIも存在します。下記のAPIは今後は使わないようにしてください。v0.12は互換性はあるのかJavaScriptのレイヤは互換性があります。ほとんどのモジュールはそのまま動くでしょう。バインディングして作っているライブラリはV8がバージョンアップされたことにより、内部のABIの互換が崩れているため動かなくなります。それらのモジュールが、まだv4.0に対応するまではアップグレードをしても動きません。C/C++のnativeモジュールの問題で動いていないモジュールを確認するためにはこのissueを確認していただくとよいと思います。v5にはついていません。v5は次のバージョンが出たらサポートされなくなります。LTSの対象になるのは偶数のバージョンとされています。偶数のバージョンが必ずLTSというわけではなく、今のところ偶然そういうバージョンになっているというのが正しい状態なので、きちんとLTSかどうかを把握するためには、バージョン番号の他にLTS識別名(ArgonやBoron等の元素名)が付いていることを確認したほうがよいです。確認するには、公式サイトのトップページに書いてある情報から識別するのが簡単です。公式サイトv0.10からv0.12までのLTSプランについては下記の図を参考にしてください。v5には、npmのバージョン3やALPNサポートがついています。v5.0は前述したとおりLTSバージョンではないので次のバージョンからはサポートされません。最新の機能を使ってみたい方向けのバージョンになります。v5を利用するのがいいかと思います。v4.0がリリースされました。実際にすでにプロダクションで使っているところもある安定したバージョンになります。v4.0には新しいJavaScriptであるES2015の機能が使えるようになっています。APIにもいくつか変更があるのと、性能が改善されています。LTSということで、今から2年半、2018年4月まではメンテナンスされる予定です。v5もすでにリリースされていますが、これは今のところ最新の機能を使ってみたいedgeなエンジニア向けのバージョンです。バージョンの違いを意識した上で利用してください。Node.jsのv0.10やv0.12を使っている人たちはまだ多いと思いますが、来年の末には両方のバージョンともにサポートが切れるので、今のうちから新しいバージョンにバージョンアップを検討しておくことをおすすめします。