はじめに
Node.js の登場から8年たちますが、未だに「Node.jsとは一体何か?」という疑問を持つ人は多いと思います。Wikipediaによれば
Node.jsとはイベント化された入出力を扱うUnix系プラットホーム上のサーバサイドJavaScript環境である(V8 JavaScriptエンジンで動作する)。
だそうです。また別の説明では
Node.jsの第1の目標は「スケーラブルなネットワーク・プログラムを作成するための簡単な方法を提供すること」
となっています。
こんな言い方をするから混乱するのだと私は思います。私の理解はこうです。
Node.jsとは、Google Chromeに搭載されている高速なJavaScriptエンジンV8をコマンドラインから使えるようにしたJavaScript言語処理系。付属ライブラリはノンブロッキングI/Oを特徴とし、そのライブラリを使うにはブラウザ上のJavaScriptとは異なる構文を用いる。
これは3つのことを言っています。
- Node.jsとはJavaScript処理系である
- 付属ライブラリはノンブロッキングI/Oが特徴である
- ライブラリの参照方法が異なるため、ブラウザ上のJavaScriptと互換性がない
Node.js とは何か
1はNode.jsの「定義」ですが、これをはっきり言わないから混乱するのだと思います1。要はjavaコマンドやperlコマンドと同じです。node hoge.js
で hoge.js に書かれたJavaScriptのプログラムを実行します。node
とだけタイプすると対話モードに入るので、インタフェースはshに近いといえるかもしれません。
2はNode.jsが作られた本来の目的です。コールバックを用いてI/Oを非同期で処理するプログラミング・スタイル(Ajaxのスタイル)をディスクI/Oにまで適用しました。これにより、I/Oがブロックしてもプログラム自体はブロックせず、単一のスレッドでも並列して処理できるようになりました。新たにプロセスやスレッドを起こさないので計算機資源が節約できるというわけです。思うに「ノンブロッキングI/O」という用語が誤解を生む元です。I/Oはブロックしますがプログラムはブロックしないのです。
3は大きな問題です。Node.jsは他のプログラミング言語と同じく「プログラムから必要なモジュールを指定」できるようになりました2が、ブラウザ上のJavaScriptで問題となっていた名前の衝突を避けるために、大域変数を全く使わない方法を採用しました。逆にブラウザ上のJavaScriptではグローバル変数以外にファイルをまたがったコードを参照する方法がないので、両者は互換性がない状態となってしまいました。
フロントエンド開発とNode.js
現在Node.jsは、本来の目的であったサーバサイドの処理よりも、むしろクライアントサイドで使われる傾向にあります。モジュール管理ツール npm のリポジトリが活況を呈しているため、開発者はクライアントサイドのモジュールであってもnpm向けに提供することを選択するようになっています。このためクライアントサイドでもNode.jsを使う必要が出てきました。この事情を知らないと「Node.jsって何?何が嬉しいの?」ということになるのではないでしょうか。クライアントサイドではI/Oのブロックの問題はAjaxによりとっくに解決済みでしたから。
しかしながらNode.jsの利用を前提としたフロントエンド開発には未だスタンダードになる組み合わせがなく、大変混乱しているように見えます。これがまたNode.jsの分かりにくさに拍車をかけています。少し整理してみます。
トランスパイラ
ライブラリ参照方法の非互換により、Node.jsスタイルで書かれたプログラムをブラウザ上で動作させるには変換が必要になります。これを行うプログラムをトランスパイラと呼んでいます。この本来の意味で現在主流なのは webpack だと思います。
どうせ変換が必要なら、ということでJavaScriptの最新仕様を多くの処理系上でも動作するよう変換する Babel や、さらに先を行って別言語からJavaScriptに変換する CoffeeScript、TypeScriptといったトランスパイラもあります。
タスクランナー
変換という一処理が入ったため、makeのような依存性を意識した作業自動化のツールが欲しくなります。これを行うプログラムをタスクランナーと呼んでいます。少し前までは gulp、Grunt といったタスクランナーが流行ったようですが、機能が豊富で設定が複雑になりすぎたため、今では npm の提供する npm-scripts と呼ばれる機能に原点回帰しているようです。3
テスティング・フレームワーク
今までフロントエンド開発では試験の自動化がしにくかったため、テスティング・フレームワークが採用されることはまれでした。ですがNode.jsによりバッチ処理ができるようになったため、自動テストが行われるようになってきているようです。テスティング・フレームワークでは Mocha が人気です。
Web上の記事を見ていると、むやみに開発環境を複雑にしているように感じます。何のためにNode.jsを利用するのか考え、環境をシンプルにすべきと思います。4