ここから本文です

3分で読める、ITキーワード解説:webpack(バンドリングツール)

@IT 7月26日(火)6時10分配信

●webpackとは

 webpackは、Webアプリ(のクライアントサイド)の開発時にアプリを依存関係のある複数のモジュールに分割している場合に、最終的にそれらのファイルを1個以上のファイルにまとめてくれるバンドリングツールだ。

【その他の画像】Webアプリの実行画面

 最近ではWebアプリ(のクライアントサイド)開発でもNode.jsなどで提供されているモジュール機構を使うことで、コードを複数のモジュールに分割するのが一般的になっている。ただし、アプリが複数のモジュールで構成される場合、それらの間の依存関係を開発者が手作業で管理したり、特にアプリの規模が大きくなってきたときに全てのファイルを問題なくブラウザ内に読み込んだりするのが難しくなる。そこで、モジュール間の依存関係を解析して、最終的に複数のモジュールを1つのファイルにまとめてブラウザに読み込ませるのを容易にする手段として、本稿で見るwebpackなどのバンドリングツールが大きな価値を持つようになっている。

 Webpackではバンドリングの対象はJavaScriptコードに加えて、CSSファイルや画像ファイルなどもスタティックなアセットにまとめることができる。また、コード分割(Code Splitting)機能を使うことで、必要なときに必要なコードを読み込むようにすることも可能だ。webpackの特徴を以下に示す。

・ファイル間の依存関係を基に、それらを1つ以上のチャンク(ファイルを結合した単位)にまとめ、オンデマンドでロードできる。これにより、大規模なWebアプリの初期ロードに必要な時間が軽減される
・静的なアセット(JavaScriptコードや画像ファイル)をモジュール化可能
・サードパーティーライブラリもモジュール化できる
・ローダーやプラグインによる拡張性

 このようにその対象がJavaScriptコードだけにとどまらない、オンデマンドで必要なもの(チャンク)だけをロードできるといった特徴から最近では人気が高まってきている。以下では例を見ながら、webpackの使い方の基本とその特徴を幾つか紹介する。

●簡単なサンプル

 まずはシンプルなWebアプリをNode.jsベースで作成して、それをwebpackでバンドリングしてみる。なお、本稿ではwebpackのインストールには「npm install webpack --save-dev」コマンドと「npm install webpack -g」コマンドの両者を実行している。また、jQueryも使用している。

 作成するのはHTMLファイルを1つとJavaScriptファイルを3つだ。これらのコードを以下に示す。

・Hello Worldプログラム
// moduleA.js
module.exports.hello = "Hello";

// moduleB.js
module.exports.world = "world";

// app.js
var moduleA = require('./moduleA');
var moduleB = require('./moduleB');
var $ = require('jquery');

$('h1').text(moduleA.hello + ', ' + moduleB.world);

<!doctype html>
<html>
<head>
<title="DevBasics/keyword webpack">
<charset="utf-8">
</head>
<body>
<h1></h1>
<script src="./app.bundle.js"></script>
</body>
</html>


 HTMLファイル側で読み込むJavaScriptコードの名前は「app.bundle.js」という名前にしてある(webpackでファイルをまとめる際にはこのファイル名を指定する)。

 app.jsファイルは2つのモジュール、moduleA.jsファイルとmoduleB.jsファイルに依存していて、require関数でこれらをインポート/利用している。では、これらのファイルをwebpackでまとめてみよう。これによりwebpackが依存関係を解析し、必要なファイルを1つのファイルへとバンドリングしてくれる。

 これには「webpack エントリポイントとなるファイル 出力ファイル」コマンドを実行する。ここでは出力ファイルの名前には上で述べたように「app.bundle.js」を指定している。

・webpackコマンドの実行結果
>webpack app.js appbundle.js
Hash: 0484cfc1ab86676663a5
Version: webpack 1.13.1
Time: 806ms
Asset Size Chunks Chunk Names
appbundle.js 274 kB 0 [emitted] main
[0] ./app.js 168 bytes {0} [built]
[1] ./moduleA.js 50 bytes {0} [built]
[2] ./moduleB.js 50 bytes {0} [built]
+ 1 hidden modules


 これで3つのJavaScriptファイル(に加えてjQueryのファイル。これが上の出力の「hidden module」のことだ)が1つのファイルにまとめられた。これを実行すると次のようになる。

○webpack構成ファイル

 webpackでは構成ファイルを記述しておくと、コマンドライン引数なしでwebpackコマンドを実行するだけで、バンドリング処理を行える。webpackの構成ファイルの名前は「webpack.config.js」。例えば、ここで行っている処理を構成ファイルに記述すると次のようになる。

・webpackの構成ファイルの内容
module.exports = {
entry:'./app.js',
output: {
filename: './app.bundle.js',
}
}

 見れば分かる通り、entryプロパティにはエントリポイントとなるファイル名を、outputプロパティには出力先を指定する(ここでは省略しているがpathプロパティで出力先のディレクトリも指定可能)。これでwebpackコマンドを実行すれば、app.bundle.jsファイルが生成される。

○CSSファイルのバンドリング

 今度はこれにCSSのスタイルを定義したsytle.cssファイルを追加して、これをapp.bundle.jsファイルにバンドリングしてみよう。style.cssファイルの内容を以下に示す。

・style.cssファイルの内容
body {
background-color: lightgray
}

 このスタイルを適用するには、通常は<link>タグを使用するが、ここではHTMLファイルには変更を加えずに、app.bundle.jsファイル内にこの内容を埋め込む。これにはapp.jsファイルを次のように変更する。

・変更後のapp.jsファイル
var moduleA = require('./moduleA');
var moduleB = require('./moduleB');
var $ = require('jquery');
require('./style.css');

$('h1').text(moduleA.hello + ', ' + moduleB.world);


 さらにstyle-loaderとcss-loaderの2つのnpmパッケージをインストールしておく必要もある(「npm install パッケージ名 --save-dev」コマンドでインストール)。名前から分かるように、これはwebpackが持つ「ローダー」と呼ばれる機能を利用したもので、他にもJSONファイルを読み込むためのjson-loader、Babelを使用してECMAScript 2015コードをJavaScript 5コードに変換するbabelローダーなど、さまざまな種類のローダーが提供されている。

 最後にwebpack.config.jsファイルに以下の記述を追加する。

・変更後のwebpack.config.jsファイル
module.exports = {
entry:'./app.js',
output: {
filename: './app.bundle.js',
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
}


 後はwebpackコマンドを実行するだけだ。これにより、スタイル指定までを含んだapp.bundle.jsファイルが生成される。実行結果を以下に示す。

 このように、webpackを使用すると、JavaScriptファイルだけではなく、さまざまな種類のファイルまでを1つのファイルにパッケージングできる。また、本稿では取り上げなかったが、コードスプリット(Code Splitting)機能を利用すると、必要なファイルを必要なタイミングで読み込めるようになる。SPA(Single Page Application)などを開発している際に、特定のルートでのみ必要になるデータをオンデマンドで読み込みたいときには便利に使える。

 webpackは、依存関係のある複数のモジュールやファイルを1個以上のファイルにまとめてくれるバンドリングツールだ。本稿で見たように、その対象はJavaScriptファイルだけにとどまるものではなく、ローダーを活用することでさまざまな種類をバンドリングしたり、ECMAScript 2015やTypeScriptで書かれたコードをJavaScript 5コードに変換したりといったことが可能になる。また、オンデマンドで必要なデータを読み込めるなど、実践的なWebアプリを開発する上で役に立つ機能が提供されている。

●参考資料

・webpack: webpack公式サイト
・webpack入門: 「webpack-howto」の「ossan-engineer」氏による和訳

[かわさきしんじ,Insider.NET編集部]

最終更新:7月26日(火)6時10分

@IT