やりたいこと
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));
});