webpackとは?使い方と導入するメリットをわかりやすく解説

webpackをご存知ですか?

webpackは、JavaScriptなどの複数のモジュールをひとつにまとめるツールです。

この記事では、webpackの使い方と導入するメリットについて詳しく解説します。使い方の解説では、実際にモジュールを指定してひとつにまとめる作業を実行し、ファイルに出力するまでを、コードを用いて詳しく解説しています。

後半では、コードの圧縮方法や便利なプラグインなど、より実践的な内容を説明していきます。現在、フロントエンド開発で発生した複数のjsファイルをまとめたい方や、画像ファイルを整理したい方、実践的に使いたい方におすすめです。

【基礎編】

webpackとは?

webpackは、モジュールを束ねるツールです。

モジュールとは、プログラム内のJavaScriptファイル(以下:jsファイル)やsassファイルなどのことです。webpackを使うことで、複数のjsファイルをひとつのjsファイルにまとめたり、複数のsassファイルをひとつのsassファイルにしたりできます。

バンドル(bundle)は”束にする”という意味です。上の画像に「bundle  your style」とありますが、文字どおりwebpackはモジュールを”束にする”役割を担います。

webpackを導入するメリット

複数のファイルをスッキリひとつにまとめることで、どんなメリットがあるのでしょうか?具体的には以下のような利点が挙げられます。

  • コードが読みやすくなる
  • 保守性が高くなる
  • コードを他プロジェクトに転用しやすくなる
  • JSだけでなく、CSSや画像もバンドルできる
  • 包括的な開発環境が整う(開発作業の分担やテストがしやすくなる)

また、webpackは開発側だけでなく、ユーザー側にもメリットがあります。たとえばjsファイルがまとめられ依存関係が解消されていれば、ブラウザでjsファイルを読み込む際にそれほど時間がかかりません。

スピーディな読み込み速度は、ユーザビリティ向上につながります。

webpackの使い方

ここではまず、複数のjsファイル(モジュール)を束ねてファイルを出力する方法をご紹介します。

1. webpackの環境構築する

まずはwebpackをインストールしましょう。

「グローバルインストール」と「ローカルインストール」という2通りのインストール方法があります。おすすめは後者の「ローカルインストール」です。前者は目的のプロジェクト以外の環境にも影響するので、他の環境に影響しないローカルインストールがおすすめです。

【グローバルインストール】

$ npm install webpack -g

【ローカルインストール】

npm install webpack --save-dev

 

▲ディレクトリ構成と各ファイルの詳細

▲ディレクトリ構成と各ファイルの詳細

2. ファイルを設定する

webpackの利用を開始するには、まずwebpack.config.jsに設定を記述します。以下のように設定してみましょう。

// output.pathに絶対パスを指定する必要があるため、pathモジュールを読み込んでおく
const path = require('path');
module.exports = {
// モードの設定、v4系以降はmodeを指定しないと、webpack実行時に警告が出る
mode: 'development',
// エントリーポイントの設定
entry: './src/js/app.js',
// 出力の設定
output: {
// 出力するファイル名
filename: 'bundle.js',
// 出力先のパス(v2系以降は絶対パスを指定する必要がある)
path: path.join(__dirname, 'public/js')
}
};

ちなみに、コード中で出てきたもので覚えておいた方がいいものは以下の2つ。

  • entry:エントリーポイントを設定します。エントリーポイントとは、モジュール間の依存関係の解析をするスタート地点です。メインの処理をする主役でもあります。
  • output:出力されるファイル名や出力先のパスを設定します。

3. エントリーポイントで2つのファイルをまとめる

ここで2つのファイルをバンドルさせます。ふたつの言葉を足して合わせるという処理ができれば成功です。

コードはこんな感じです。

import module1 from './modules/module1';
import module2 from './modules/module2';
//変数を定義します
var word1 = "This is";
var word2 = " a pen.";
//関数に変数を投入します
var returnedWord1 = module1(word1);
var returnedWord2 = module2(word2);
//結果をまとめて表示します
var addedWords = returnedWord1 + returnedWord2;
console.log(addedWords);

importを使って呼び出すのがミソです。

4. “モジュール1″を定義する

エントリーポイントでimportを使って呼び出すためには、モジュールを定義する必要があります。

export defaultでmodule1をモジュールとして定義しました。

export default function module1(word1) {
return word1 + "(これは)";
}

5. “モジュール2″を定義する

モジュール1と同様に作成していきましょう。

export default function module2(word2) {
return word2 + "(ペンです。)";
}

6. webpackでJSファイルをまとめる

いwebpack.config.jsがある階層でwebpackコマンドを実行すると、ファイルがバンドルされます。ファイルが作成される場所は、先ほどconfigファイルで設定したところです。名称も設定通りになっているか確認しましょう。

作成されたファイルを開いてみると、以下のようになっています(実際のファイルはかなり長大になってしまったので、一部抜粋しています)。

/***/ "./src/js/app.js":
/*!***********************!*\
!*** ./src/js/app.js ***!
\***********************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _modules_module1__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modules/module1 */ \"./src/js/modules/module1.js\");\n/* harmony import */ var _modules_module2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/module2 */ \"./src/js/modules/module2.js\");\n\n\n//変数を定義します\nvar word1 = \"This is\";\nvar word2 = \" a pen.\";\n//関数に変数を投入します\nvar returnedWord1 = Object(_modules_module1__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(word1);\nvar returnedWord2 = Object(_modules_module2__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(word2);\n//結果をまとめて表示します\nvar addedWords = returnedWord1 + returnedWord2;\nconsole.log(addedWords);\n\n//# sourceURL=webpack:///./src/js/app.js?");
/***/ }),
/***/ "./src/js/modules/module1.js":
/*!***********************************!*\
!*** ./src/js/modules/module1.js ***!
\***********************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return module1; });\nfunction module1(word1) {\nreturn word1 + \"(これは)\";\n}\n\n//# sourceURL=webpack:///./src/js/modules/module1.js?");
/***/ }),
/***/ "./src/js/modules/module2.js":
/*!***********************************!*\
!*** ./src/js/modules/module2.js ***!
\***********************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return module2; });\nfunction module2(word2) {\nreturn word2 + \"(ペンです。)\";\n}\n\n//# sourceURL=webpack:///./src/js/modules/module2.js?");
/***/ })
/******/ });

バンドルされていることがお分かりでしょうか。

また、作成されたファイルを読み込んだHTMLファイルを作成し、ブラウザで開いてみてください。コンソールを確認し、正常にjsファイルが動作していることを確かめてみましょう。

module1の(これは)を足す処理と、module2の(ペンです)を足す処理が正しくおこなわれていることがわかります。

【実践編】

webpackの便利な機能5選

1. webpackでコード圧縮、ソースマップを使う

ここからは少し実践的になります。

webサイトでは多くの画像やcssファイル、jsファイルが使われており、多くの容量を占めています。webpackを使うと、それらをすベてまとめられ、容量を節約できます。

ファイルを圧縮するときは、元のソースファイルとの関連が分かるよう、ソースマップも有効にしましょう。

先ほどのconfigファイルのmodeという項目に注目してみてください。これはwebpack 4から導入された項目で、3つのモードが存在します。

development ソースマップが有効になる
production ファイルを圧縮する
none  特にない

deveropmentに設定すると、容量は大きくなりますがビルド時間が短くなります。そこで、開発時はdevelopment、サイト公開時はproductionに設定するのが良いでしょう。

2. ファイルの変更を検知するwatchモード

ファイルの変更を検知する機能のことです。オプション指定でwebpackコマンドを実行するか、configファイルに設定を記述すれば使用できます。

ビルド時間を短縮する効果があるので、ぜひwatchモードは活用しましょう

webpack --watch

または、

const path = require('path');
module.exports = {
// watchモードを有効にする
watch: true,
mode: 'development',
entry: "./app.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, 'public/js')
}
}

3. ローダーでサブファイルも変換

ローダーとは、imageやcssなどjs以外のファイルを変換したり、バンドル前にそれらのモジュールに何かしら働きかける機能のことです。ローダーによってその機能はさまざまです。開発で役立ちそうなローダーをいくつかご紹介しましょう。

  • Babel
    Babelは、ES6をES5に変換するコーダーです。ESはECMASCriptの略称で、JavaScriptの標準(「JavaScriptはこういうルールで書きましょうね〜!」と定められている基準)のことです。”Ecma International”という団体によって定められています。“Ecma International”という団体は、Microsoft・Google・Appleなどの企業の人たちで構成されており、新しい言語の登場や、ブラウザの進化などに合わせて標準を更新しています。ES5は2009年12月、ES6は2015年の6月にリリースされたものです。6年間にさまざまな変更があったので、ES5で書かれたコードをES6に変換するBabelは一定の需要があります。インストール方法は以下の通り。
    $ npm install babel-loader babel-core --save-dev

    インストールできたら、configファイルにloaderの設定を追記しましょう。

    // output.pathに絶対パスを指定する必要があるため、pathモジュールを読み込んでおく

    const path = require('path');
    module.exports = {
    // モードの設定、v4系以降はmodeを指定しないと、webpack実行時に警告が出る
    mode: 'development',
    // エントリーポイントの設定
    entry: './src/js/app.js',
    // 出力の設定
    output: {
    // 出力するファイル名
    filename: 'bundle.js',
    // 出力先のパス(v2系以降は絶対パスを指定する必要がある)
    path: path.join(__dirname, 'public/js')
    },
    // ローダーの設定
    module: {
    rules: [
    {
    // ローダーの処理対象ファイル
    test: /\.js$/,
    // ローダーの処理対象から外すディレクトリ
    exclude: /node_modules/,
    use: [
    {
    // 利用するローダー
    loader: 'babel-loader',
    // ローダーのオプション
    // 今回はbabel-loaderを利用しているため
    // babelのオプションを指定しているという認識で問題ない
    options: {
    presets: [['env', { modules: false }]]
    }
    }
    ]
    }
    ]
    },
    };

    これでwebpackコマンドを実行すると、どのブラウザでもES2015で書かれたコードが動作するようになります。

  • css-loader
    CSSをバンドルするには「style-loader」と「css-loader」が必要です。まずはインストールから。
    $ npm install webpack webpack-cli style-loader css-loader --save-dev
    configファイルに以下のように追記しましょう。
    module.exports = {
    // モード値を production に設定すると最適化された状態で、
    // development に設定するとソースマップ有効でJSファイルが出力される
    mode: 'production',
    module: {
    rules: [
    {
    test: /\.css/,
    use: [
    'style-loader',
    {loader: 'css-loader', options: {url: false}},
    ],
    },
    ]
    }
    };
    この場合、cssを読み込んでjsにバンドルするcss-loaderが先に実行され、続いて<link>タグにcssを展開するstyle-loaderが機能します。コード内に登場するuseについては次に説明します。

4. useでローダーを複数使用する

useを使用すると、複数のローダーを使うことができます。

module: {
rules: [{ test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: [['env', { modules: false }]]}
},
{
loader: 'jshint-loader'
}
]}
]

これは便利な機能ですよね!

注意してほしいのは「後ろから順番に適用される」ということです。

5. 便利な3つのプラグイン

便利なプラグインの名前と用途を3つご紹介します。

  • ContextReplacementPlugin:差分を検知し、差分があった場合は自動で置き換えてくれる
  • IgnorePlugin:正規表現に引っかかるモジュールを作成しないようにしてくれる
  • UglifyJsPlugin:不要なスペースやコメントを削除しファイルを圧縮してくれる

プラグインを追加すると、ビルド実行時にさまざまな機能を使えます。

機能を追加する点でローダーと似ているようにみえますが、ローダーはバンドル前、プラグインはビルド実行時に追加されるという違いがあります。

webpack移行の注意点

webpackでは、最新版へのバージョンアップが絶えずおこなわれています。

webpack3からwebpack4などにバージョンを変更する場合、移行後の環境ではこれまで使えていたローダーやプラグインが利用できないことがあります。事前に確認しておきましょう。

移行に失敗した場合は、node_modulesフォルダを削除してから以下のようにコマンドを叩き、最新版をインストールしてみましょう。

npm install

まとめ

いかがでしたか?

webpackを使用すると、煩雑なファイルをスッキリまとめることができます。それによってコードが読みやすくなり、メンテナンスもしやすくなるでしょう。

また、cssや画像ファイルなどもまとめられ、ブラウザ依存を解決したり、UXを向上させる効果もあります。

基本的にファイルをまとめる(バンドルする)のがwebpackの役割ですが、ローダーやプラグインと呼ばれる外部機能と連携させることでフロントエンド開発の幅が広がります。

みなさんもぜひwebpackを試してみてください!

SHARE

  • 広告主募集
  • ライター・編集者募集
  • WorkshipSPACE
週2日20万円以上のお仕事多数
Workship