NOANAVI

BLOG

【webpack v4】最適なビルドと問題点をsplitChunksPluginで解決とキャッシュ対策

まずは、前回前々回の記事をご覧になられていない方はお先に下記の記事をご覧いただき、この記事をご覧いただければと思います。

こちらが前々回の環境構築からサンプルな構成でのbuildを行っております。

こちらが前回の記事で様々な機能やプラグインを紹介しております。

今回の内容では、前回ビルドした『app.bundle.js』と『another.bundle.js』では
最適なビルドがされていないためこの記事で詳しくご説明いたします。

現在の問題点とは?

前回ビルドした『app.bundle.js』と『another.bundle.js』はともにjqueryとvelocity-animateがバンドルされてしまっています。

つまり

『app.bundle.js』には『app.js』『jquery』『velocity-animate』
『another.bundle.js』には『another.js』『jquery』『velocity-animate』

これらがバンドルされてしまって重複しファイル容量が増えています。

またもう1つの問題として更新頻度が高いエンドリーポイントのファイルと更新頻度が低い『jquery』などがバンドルされているためキャッシュを活用できない問題があります。

splitChunksPluginを使用する

splitChunksPluginでは複数のエンドポイント間で共通して使用しているモジュールをバンドルしたファイルを出力できます。

jqueryとvelocity-animateをバンドルしたvender.jsを出力し、app.bundle.jsとanother.bunble.jsで利用します。下記画像をご覧いただくとイメージしやすいかと思います。

デフォルトでのsplitChunksPluginの設定条件を満たしていないため、
jqueryとvelocity-animateのみバンドルされたファイルが出力されていないので設定を上書きします。

webpack.common.jsを更新

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    app: './src/js/app.js',
    another: './src/js/another.js',
  },
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: 'js/[name].bundle.js',
    chunkFilename: 'js/[name].js', //追加  エンドポイント以外からの出力名を指定
  },
  optimization: { //追加
    splitChunks: {
      chunks: 'initial', //静的import(通常import)が対象になる、デフォルトの指定
      name: 'vendor', //分割して出力するファイル名
    },
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/html/index.html',
      chunks: ['app'],
    }),
    new HtmlWebpackPlugin({
      filename: 'another.html',
      template: './src/html/another.html',
      chunks: ['another'],
    }),
  ],
};

ビルドし確認すると、public/js/vender.jsが作成され『app.bundle.js』『another.bundle.js』で動いていることが確認できます。

splitChunksPluginの応用

splitChunksPluginで設定を変更し、複数のファイルを出力します。

今回は仮で、src/js/modulesにjsファイルを作成し、『app.js』『another.js』にimportし使用します。

下記の設定では、jqueryとvelocity-animateをバンドルしたファイルと、src/js/modulesに作成したファイルだけをバンドルしたファイルの2つを出力する設定になります。

下記のようにwebpack.common.jsを書き換えます。

optimization: {
  splitChunks: {
    chunks: 'initial', //共通の設定
    cacheGroups: { //分割したファイルの設定を行う
      vendor: { //jqueryとvelocity ここの名前はわかりやすいので◯
        test: /node_modules/, //分割対象を指定
        name: 'vendor', //出力ファイル名
      },
      vendorsModules: { ここの名前はわかりやすいので◯
        test: /src[\\/]js[\\/]modules/, //分割対象を指定
        name: 'vendor-modules', //出力ファイル名
        minSize: 0, //分割する最小ファイルサイズが小さい場合は指定
        minChunks: 2, //モジュールが使われている箇所の最小値
        },
      },
    },
  },

ビルドし確認するとpublic/js にvendor.jsとvendor-modules.jsが出力されます。

キャッシュ対策について

キャッシュは便利なイメージがありますがその反面、最新のバージョンが反映されないことでエラーやバグが発生してしまう原因に繋がります。

そのためwebpackでは[contenthash]を使用し解決します。

webpack.common.jsのoutputを書き換える

上記のような記述をするだけで、毎回ハッシュを変更してくれます。

filename:'js/[name].[contenthash].js', //変更
chunkFilename:'js/[name].[contenthash].js' //変更