JavaScript
webpack

Webpack はじめの一歩

More than 3 years have passed since last update.

このページは作業ログです。やったことをつらつら書くだけなのでまとめません。あしからず。


モチベーション

JavaScript界隈のビルドツールは雨後の筍のように色々あるね。GruntやらGulpやらはたまたmakeを使いましょうっていう記事もある。最近出てきたWebpackがReact界隈だとよく使われているので試してみる。


チュートリアルをやってみる


  1. まず最初は設定ファイル無しから始まる。entry.jsを用意しただけの所からbundle.jsをwebpackで作り、htmlに読ませる。

  2. 次も設定ファイルなし。require文を使って他のファイルの内容を読み込んだentry.jsを作り、htmlの読み込ませる。

  3. 引き続き設定ファイルなし。npm install css-loader style-loaderを実行してローダーを追加。node_modulesにあるローダーを追加するらしい。マジか。もう一個ビックリしたのがjsファイルにcssのロードを書くのか。マジか。

  4. 設定ファイルなんかない。require("!style!css!./style.css");!style!css!っていうのはローダーの指定だったんです。(ここまで解説ない)ローダーの指定はコマンド実行時にも指定できるよ、っていうのがここ

  5. やっとこさ設定ファイル登場。webpackはカレントディレクトリにあるwebpack.config.jsを自動で利用する。

  6. 進捗を出したい時はwebpack --progress --colorsというように打つ。

  7. ファイルの変更監視するwatchモードあり〼webpack --progress --colors

  8. 開発用サーバーもあるでよ。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周り


webpack.config.js

   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 modelazy 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}


server.js

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でも使えるけど、実験的機能という位置づけで、バグもあるだろう、という機能。


参考URL