webpack学習の基本のき

こんにちは!ファンデリー デザイン・システム室の町田です。

前回は『React+Reduxで書く時に気をつけていること』という記事で、React開発時のディレクトリ構成や社内のコーディング規約的な内容のお話を書かせていただきました。

そして今回はReact + Rails環境下での”設定周り”のお話、特にWebエンジニアにとって、今後“必須の知識”になりつつある『webpack』について書いていきたいと思います。


はじめに

現在、React.jsやVue.js、Angular等のJavaScriptフレームワークが主流となってきたことで、JavaScriptのバンドラーであるwebpackの知識は、Webエンジニアにとって最低限身につけておくべきものになってきたと感じています。

本記事では、webpackの”名前は知っているけれど中身についてはよく知らない”という方向けの記事となっています。
これを機に、少しでもwebpackに興味を持っていただくことで、皆さんが「webpackのことをもっと良く知りたい」と思うきっかけになれば幸いです。


バージョン情報

名称 バージョン
webpacker 4.0.2
Ruby 2.6.0
Rails 6.0.0
React 16.8.6
Node.js 12.13.1
Yarn 1.16.0


webpackとは

オープンソースのJavaScriptモジュールバンドラーです。
具体的には、Webアプリケーションを構成するリソース(jsファイル、cssファイル、画像ファイル等々)を一つにまとめてくれるツールです。(下図参照)

webpackでリーソスをbundleする(束ねる)
webpackでリーソスをbundleする(束ねる)


webpackwebpackerの違い

webpackについて検索をしていると、webpackerというものも検索結果に出てくると思います。
名前が似ていて少しややこしいですが、webpackerはRailsのgemの1つです。
webpackは色々な設定ができる分、学習コストがやや高いのが難点ですがwebpackerwebpackの中身を良く知らなくても、良い感じにwebpackを動かしてくれる優れものです。

webpackerはWebアプリケーションで一般的に良く使われるメジャーな設定を、標準で実装してくれるwebpackのラッパーです。

弊社では、Rails上で運用しているプロダクトが多いので(Rails6.0よりwebpackerが標準実装になりました)webpackerの話も交えつつ、ただし、webpackerの本質を理解するためには、webpackのことも理解しておく必要があるので、webpack目線での話をメインに進めたいと思います。


webpackが無いとどうなるの?

・特定のブラウザでES6構文が使えない
・ファイルの取得時間が増える
・規模が大きくなると管理が辛くなる
など

Rails6.0以降のプロジェクトかつ、ある程度の規模感であれば、標準実装されているwebpack(er)をあえて外す理由は無さそうです。


ローダー

リソースをモジュール化するためのツールのこと。

上図で説明した通り、webpackはモジュール化されたものをバンドルする(束ねる)ことができるツールです。
逆に言えば、モジュール化されていないものはバンドルすることができません。
そのため、画像ファイルやスタイルシートなどのリソースは、このローダーを通じてモジュール化させてあげることで、はじめてバンドルができるようになります。(下図参照)

ローダーによるモジュール化
ローダーによるモジュール化


ローダーはリソースの種類に合わせて使い分けます
以下でバンドル方法の例を紹介します。

(webpackerを使用している場合、下記ローダーは標準実装されているため、あえて実装する必要はありません。webpackの理解を深めるため便宜上記述しています)


(1)スタイルシートのバンドル

webpack.config.js
module.exports = {

    ...中略...

    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    // style要素としてページに反映させるためのローダー
                    'styleloader',
                    // スタイルシートを読み込むためのローダー
                    'css-loader'
                ]
            }
        ]
    }
};


(2)画像ファイルのバンドル

webpack.config.js
module.exports = {

    ...中略...

    module: {
        rules: [
            {
                // 他のファイル形式もバンドルしたい場合はここに追加
                test: /\.(gif|png|jpg)$/,
                use: [
                    { loader: 'urlloader' }
                ]
            }
        ]
    }
};


Babel

BabelはJavaScriptのトランスコンパイラー(変換ツール)です。
このBabelを介すことで、ES6(ECSAScript2015、ES2015)の標準化されたJavaScript構文を、ES6サポート対象外のIE11などでも解釈することができるようになります。
そのため、現在webpackを新しく導入する際は『webpack』と『Babel』とを組み合わせて使用するのが通例です。

Babelのトランスパイル
Babelのトランスパイル


Babelの設定方法は以下です
(こちらもwebpackerを使用している場合、標準実装されています


webpack.config.js
module.exports = {

    ...中略...

    module: {
        rules: [
            {
                test: /\.js$/,exclude:/node_modules/,
                use: ['babelloader']
            }
        ]
    }
};
.babelrc
{
    "presets":[
        [
            "env",
            {
                "modules": false
            },
            "react"
        ]
    ]
}


プラグイン

webpackにはたくさんの便利なプラグインが存在します。
特に有用なのが、SplitChunksPlugin

複数のエントリポイント(アプリケーションの入り口)で共通のライブラリを使っている場合、それぞれのファイルに対して個別にバンドルするのではなく、ライブラリだけ別のファイルとして出力することで、全体のファイルサイズが小さくなるといったメリットを得ることが出来ます。

SplitChunksPluginの仕組み
SplitChunksPluginの仕組み


SplitChunksの適用の仕方は以下の通りです。


webpackの場合

webpack.config.js
module.exports = {
  entry: {
    app: './src/js/app1.js',
    app2: './src/js/app2.js',
    app3: './src/js/app3.js',
  },
  output: {
    filename: '[name].bundle.js',
    path: path.join(__dirname, 'public/js'),
  },
  optimization: {
    splitChunks: {
      name: 'vendor',
      chunks: 'initial',
    }
  }
};


webpackerの場合

/config/webpack/environment.js
environment.splitChunks()
views/index.html.erb
<%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %>


まとめ

今回はwebpackの導入部分について触れてみました。
モダンなJavaScriptフレームワークのモジュールバンドラーとしてデファクトスタンダードとなったwebpackについては、今後知っておいて損はないと思います。

webpackは便利な分、色々な設定があり、学習難易度がやや高いので、少しずつ触れていきながら、理解を深めていただければと思います。


現在、ファンデリー デザイン・システム室では、エンジニアとして幅広く活躍したい方を募集しています!
今回のwebpackのような設定周りや、フロントエンド、バックエンド、インフラ等々・・・
枠にとらわれず、積極的に参加出来る環境があるので「色々なことにチャレンジしてみたい」という方、是非下記エントリーフォームよりご応募お待ちしております!


募集要項およびエントリーフォーム >