このページは作業ログです。やったことをつらつら書くだけなのでまとめません。あしからず。
モチベーション
JavaScript界隈のビルドツールは雨後の筍のように色々あるね。GruntやらGulpやらはたまたmakeを使いましょうっていう記事もある。最近出てきたWebpackがReact界隈だとよく使われているので試してみる。
チュートリアルをやってみる
- まず最初は設定ファイル無しから始まる。entry.jsを用意しただけの所からbundle.jsをwebpackで作り、htmlに読ませる。
- 次も設定ファイルなし。
require
文を使って他のファイルの内容を読み込んだentry.jsを作り、htmlの読み込ませる。 - 引き続き設定ファイルなし。
npm install css-loader style-loader
を実行してローダーを追加。node_modules
にあるローダーを追加するらしい。マジか。もう一個ビックリしたのがjsファイルにcssのロードを書くのか。マジか。 - 設定ファイルなんかない。
require("!style!css!./style.css");
の!style!css!
っていうのはローダーの指定だったんです。(ここまで解説ない)ローダーの指定はコマンド実行時にも指定できるよ、っていうのがここ - やっとこさ設定ファイル登場。webpackはカレントディレクトリにある
webpack.config.js
を自動で利用する。 - 進捗を出したい時は
webpack --progress --colors
というように打つ。 - ファイルの変更監視するwatchモードあり〼
webpack --progress --colors
- 開発用サーバーもあるでよ。
webpack-dev-server --progress --colors
Express/Socket.ioを使い、ファイル変更があったら表示しているブラウザを自動でリロードしてくれる。かしこい。
用語の整理
- Loader : 各種リソースファイルの変換方法を定義したもの。JavaScript以外のファイルも対象。node.jsで書ける。同期/非同期
- Plugin : UglifyJSのように別ツールを組み込んだり、何か処理を差し込むためのもの プラグイン一覧
なぜ webpack なのか?
Pete Hunt(Instagram.com)氏のOSCON2014での講演がわかりやすい。browserifyなどでは不十分な理由の要点を訳すと、
- browserifyやrequirejsは依存関係を解釈して統合した1つの大きなJSを生成することができるが、分割してロードすることができない。
- gruntやgulpはCSSや画像などの依存関係を解釈することができない。
- WebpackはJSだけではなくCSSやHTML等の依存関係を解釈してファイルを統合できる。また、複数のファイルに分割し、ページ毎にスクリプトをロードできる。
Configurationで気になるところ
entry周り
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./js/index.js'
],
entryに含まれるwebpack-dev-server/client?http://localhost:3000
とかwebpack/hot/only-dev-server
とかなんだろう?entryに含まれているので、webpackを実行するとこれら2つのURIからコンテンツを取得し、concatされる。concatしていいファイルかどうかが問題。それぞれざっくり推測すると
-
webpack-dev-server/client?http://localhost:3000
は名前から推測するにWebpack Dev Server
の機能をconcatするために追加しているように見える。 -
webpack/hot/only-dev-server
はHot Reloadingをサポートするためのスクリプトに見える。
それぞれについて少し見てみる。
Webpack Dev Serverとは
ドキュメントによるとWebpack Dev ServerはExpress製のサーバーで、webpack-dev-middlewareを使ってwebpack後のコンテンツを配信する。webpack-dev-middleware
はassetsをコンパイルしたものをメモリ上にキャッシュするなどを担当する。webpack-dev-middleware
は2つのモードwatch mode
とlazy mode
がある。watch mode
はコンテンツが更新され次第assetのコンパイルを行い、lazy mode
はentry pointにアクセスがあった時にassetのコンパイルを行う。webpack-dev-middleware
は、assetのコンパイルが終わるまで、コンテンツの配信を遅らせる。
[脱線]APIサーバーをProxyする
フロントエンド開発時は、バックエンドサーバーと分離して開発することがあるが、そうすると大抵フロントエンドサーバーとバックエンドサーバーでポートが違うので、ブラウザのCross Origin Policyに引っかかってAPIサーバーにアクセスできない。
Webpack Dev Serverの場合もProxyできるので、特定のURIをバックエンドサーバーにプロキシを設定する。起動時のオプションに下記を追加すればよい。
proxy: {
"/api/*": "http://localhost:8080" // /api以下にアクセスがあった場合はhttp://localhost:8080に流す
}
[脱線]Webpackのログを色付けする
Webpackを使ったログを色付けするには同様に下記を追加すればよい。
stats: {colors: true}
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
stats: {colors: true}, // webpackのログを色付けする
proxy: {
"/api/*": "http://localhost:8080" // /api以下にアクセスがあった場合はhttp://localhost:8080に流す
}
}).listen(3000, 'localhost', function (err, result) {
if (err) {
console.log(err);
}
console.log('Listening at localhost:3000');
});
Hot module replacement with webpack (webpackを使ったモジュールの動的置き換え)とは
ドキュメントによるとページ再読み込みをすることなく、アプリケーションの起動中にモジュールの追加、削除を行う機構のこと。ページ毎に動的にスクリプトを読み込めるようコードを塊毎に分割している場合は、変更があったモジュールに関連するスクリプトだけ読み込み直すように設計されている。ページ全体をリロードする必要がないので、高速化が期待できる。
Productionでも使えるけど、実験的機能という位置づけで、バグもあるだろう、という機能。