LoginSignup
2
4

More than 3 years have passed since last update.

WebpackのMultiple Targetsを使ってIE11互換とそうでないjsを一度でビルドする

Last updated at Posted at 2020-07-07

やりたいこと

IE11向けのページと、そうでないページのビルドをどっちも一度のwebpackコマンドでビルドする。よくありそうなケースとしてはLPサイトはIE11向け、そうでないページはパフォーマンスを考えて少しでも容量が少なくなるようIE11互換を切りたい、二つのビルド設定が必要だがビルドは1コマンドで行いたいようなケース。またはUA判定してIEはIE11互換のjsを読み込んで、そうでないブラウザはIE11互換を切ったjsを読み込ませる、など。

動作確認済の実装

Webpack Multiple Targets

webpack.config.jsで返すwebpackの設定オブジェクトは、配列で返すことができ、それを使って複数の設定を記述できる。

caller

babel-loaderのoptionsに、babelのconfigに渡せるcallerを設定できる

babelの設定箇所(babel.config.js)で、callerを使って呼び出し元の情報を取得できる

具体的な実装

webpack.config.babel.js

import path from 'path';

export default (env, args) => {
  const isProduction = args.mode === 'production';
  const devtool = !isProduction && 'inline-source-map';
  const rules = [
    {
      test: /\.js?$/,
      use: ['babel-loader'],
    },
    {
      test: /\.css$/,
      use: ['style-loader', 'css-loader'],
    },
  ];

  const plugins = [];

  return [{
    devtool,
    entry: './entry.js',
    output: {
      path: path.join(__dirname, './'),
      filename: 'bundle.js',
    },
    module: { rules },
    plugins,
  }, {
    devtool,
    entry: './entry.js',
    output: {
      path: path.join(__dirname, './'),
      filename: 'bundle_for_ie.js',
    },
    module: {
      rules: [{
        test: /\.js?$/,
        use: [{
          loader: 'babel-loader',
          options: {
            caller: { target: 'ie11' },
          },
        }],
      }, ...rules.slice(1)],
    },
    plugins,
  }]
};

babel.config.js

const isIncludeIE11 = (caller) => caller && caller.target === 'ie11';

module.exports = (api) => {
  const includeIE11 = api.caller(isIncludeIE11);
  const targets = {
    chrome: '79',
    firefox: '72',
    safari: '13',
  };
  if (includeIE11) {
    targets.ie = '11';
  }
  const presets = [
    [
      '@babel/preset-env',
      {
        targets,
        useBuiltIns: 'entry',
        corejs: 3,
        debug: true,
      },
    ],
  ];

  const plugins = [];

  return {
    presets,
    plugins,
  };
};

結果(一部抜粋)

見やすくするためにdevelopment buildにしている

bundle.js

const buttonEl = document.getElementById('sample-button');
const inputEl = document.querySelector('[name=key]');
buttonEl.addEventListener('click', () => {
  alert(Object(_maskKey__WEBPACK_IMPORTED_MODULE_0__["default"])(inputEl.value));
});

bundle_for_ie.js

var buttonEl = document.getElementById('sample-button');
var inputEl = document.querySelector('[name=key]');
buttonEl.addEventListener('click', function () {
  alert(Object(_maskKey__WEBPACK_IMPORTED_MODULE_0__["default"])(inputEl.value));
});
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4