さて前回$を参照できないエラーが出ました。jQueryを読み込んでいなかった、というやつです。jQueryは前々回にすでにnpmでインストールしてあるので、それをrequireすれば良いわけです。./index.coffeeに追加しましょう。
#~/tutorials/project/index.coffee $= require "jquery" #これを追加 module.exports= -> $("body").append """ <h1>こんちは!</h1> """
この
#coffee $= require "jquery"
の行で、$という変数にjqueryをアサインしています。
webpackはwebpack.config.coffeeと同一のディレクトリのnode_modulesディレクトリ以下のモジュールをディレクトリ名で参照します。なので、”jquery”の一言で、jqueryのモジュールをrequireできるのです(実際にはjqueryパッケージのpackage.jsonのmainプロパティの記述に従ってjsファイルがrequireされます)。
なので、もう一度コンパイルして、ブラウザをリロードしてみましょう、、、、って言う間もなく、すでにブラウザには「こんちは!」と表示されています!
じつはwebpack-dev-serverはwebpack.config.coffeeのentryオプションで指定したソースファイル(とそのrequire先のファイル群)の変更を監視し、リアルタイムでコンパイルし、自動でリロードまで行ってくれます。(Chromeのコンソールにエラーが残っているのはSocketで非同期リロードを行っているため)。つくづく便利ですね。。。
1つ注意点。webpack-dev-serverはwebpack.config.coffeeの設定通りにバンドル作業をリアルタイムにこなしてくれますが、バンドル結果を「実際にファイルに出力していません」。全てはwebpack-dev-serverのプロセスの中でバンドル作業が行われ、バンドルされたjsはメモリから仮想的にサーブされます。今回の例でいえばbundled.jsがファイルとして吐かれていてもそうでなくてもwebpack-dev-serverには無関係です。バンドルをサーブする上でwebpack側で必要な設定は1つだけ、webpack.config.coffeeのoutput.publicPathオプションです。
#coffee publicPath: "http://127.0.0.1:3000/assets/"
このオプションによって、サーバーはブラウザからのhttp://127.0.0.1:3000/assets/bundled.js
へのリクエストに対して適切にバンドルされたjsファイルをサーブしてくれます。
これが、nodejsの特徴の一つと呼ばれる、non blocking IOというやつなのでしょうか。僕自身まだ詳しくないのですが、コストの高いファイルシステムへのIOを回避し、効率の良い動きを実現している、、、ということなのでしょう。ともあれ、開発環境の動作としてはこれは歓迎すべきことですよね、開発中のモジュールの変更をすぐにブラウザでもフォローできるということは。
このことからもみえてくるのですが、webpackは「モジュールバンドル」という開発ワークフローに、柔軟なオプションを与えてくれます。例えば、ブラウザで確認しながらコーディングなりデザインするという開発フェーズでは、バンドルをファイルに逐一落としていては時間がかかる、、、なのでwebpack-dev-serverのデーモンプロセスの中でバンドルされていれば良い。ひと段落したのち、本番環境への移行フェーズでは、webpackコマンドで本番環境用のバンドリング(Minifyしたり、バンドルするモジュールを変えたりetc)を行う、といった具合に。コマンドラインでwebpackに渡す環境変数を切り替えることで、webpack.config.coffeeの挙動もダイナミックに変更が効くので、バンドリングのレシピは、いかようにでも作ることができる、というわけです。
このあたりの実例は今後取り上げてみたいと思います。
さて、このwebpack-dev-serverはiframeをつかってレンダリングしていますが、iframeなしで動かすこともできます。ブラウザでの動作確認は、iframeだとちょっと気持ち悪いかんじがしますので、以下のようにwebpack.config.coffeeのentryオプションを変更します(その前にCtrl-C で一度サーバーを落としましょう):
#coffee entry: [ "./index.coffee" "webpack-dev-server/client?http://127.0.0.1:3000" ]
webpack-dev-serverは新たに加えたエントリの指示(webpack-dev-server/client?http://127.0.0.1:3000
)によって、開発サーバー用のスクリプト(自動リロードなど)もバンドルの中に含めるようになり、http://127.0.0.1:3000
へリクエストすればフレームレスで開発ができます。