以前、browserify + babelify + Gulp で IE11対応を試すの記事で browserify + babelify を試しましたが、今回は Webpack に挑んでみます。
ただし、プレーンな Gulp 環境ではなく、 Ususama で。
コード
package.json
// 略
"devDependencies": {
// 略
"glob": "7.1.6",
"webpack": "^5.1.3",
"webpack-stream": "^6.1.0",
"terser-webpack-plugin": "^5.0.0",
// 略
}
// 略
gulp-uglify-es
と gulp-concat
を除き、代わりに webpack
本体と Gulp で Webpack を使用するために必要な webpack-stream
、そして minifier の terser の Webpack 用プラグインである terser-webpack-plugin
を追加。
gulp/tasks/js.js
const gulp = require('gulp');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const webpack = require('webpack');
const webpackStream = require('webpack-stream');
const rename = require('gulp-rename');
const dir = {
dist: {
js: './dist/js'
}
};
const webpackConfig = require('../../weppack.config');
const jsBuild = () => {
return webpackStream(webpackConfig)
.pipe(plumber({
errorHandler: notify.onError({
message: 'Error: <%= error.message %>',
title: 'jsLibBuild'
})
}))
.pipe(rename((path) => {
path.basename += '.min'
path.extname = '.js'
}))
.pipe(gulp.dest(dir.dist.js));
};
module.exports = jsBuild;
webpack.config.js
const webpack = require('webpack');
const webpackTerser = require('terser-webpack-plugin');
const path = require('path');
const glob = require('glob');
const dotenv = require('dotenv').config();
const dir = {
src: {
js: './src/js'
}
};
const mode = () => {
return process.env.DEV_MODE === 'dev' ? 'development' : 'production';
};
const modeFlag = () => {
return process.env.DEV_MODE === 'dev' ? false : true;
};
const entry = () => {
const entries = glob
.sync(
'**/*.js',
{
ignore: [
'_plugins/**'
],
cwd: dir.src.js
}
)
.map(function (key) {
return [key, path.resolve(dir.src.js, key)];
});
return Object.fromEntries(entries)
};
module.exports = {
mode: mode(),
entry: entry(),
output: {
filename: '[name]'
},
optimization: {
minimizer: [
new webpackTerser({
extractComments: 'some',
terserOptions: {
compress: {
drop_console: modeFlag(),
},
},
}),
],
}
};
いくつかの記事を参考にしながらタスクを組みます。
自分でカスタマイズした部分は以下。
.env
でdev
,demo
,prod
のモードを切り替えているので、その部分をprocess.env.DEV_MODE
で振り分け- Webpack の設定の
mode
とterser-webpack-plugin
のdrop_console
のフラグが関係しています
- Webpack の設定の
- 複数の
.js
ファイルをエントリポイントにしたかったのでその部分はwebpackのentryファイルを複数指定、globパッケージの使い方 – Qiitaを参考に - 最終的なファイル名は
XXX.min.js
の形にしたかったのでgulp-rename
を通しました
jQuery の扱い
タスク自体は上記のやり方で走ることが確認できました( DEV_MODE=dev
)。
次は現時点ではまだ jQuery を使用しているので、 jQuery をどう読み込ませるかが課題ですが、以下のようにして動作することを確認しました。
app.js
import $ from 'jquery';
import 'jquery.easing/jquery.easing';
$(() => {
/* 処理 */
});
sitesearch.js
import $ from 'jquery';
import List from 'list.js';
//サイト内検索
export default () => {
const options = {
valueNames: ['searchTitle', 'searchText'],
};
const searchList = new List('listSearch', options);
//hits
searchList.on('searchComplete', function (a) {
$('#hits').text(a.matchingItems.length);
});
};
サイト内検索で List.js を使用しているのですが、これについてはHow am I suppose to import list.js with es6 and webpack ? · Issue #559 · javve/list.jsの Issues の方法で解決しました。
ここまでは比較的順調でした。
しかし、間も無く壁に突き当たることになります……。
TypeError: Cannot read property ‘javascript’ of undefined エラー
DEV_MODE=dev
で動作することは確認できたので、 DEV_MODE=prod
に切り替えました。
すると、以下のエラーが出てしまいました。
TypeError: Cannot read property 'javascript' of undefined
at PATH\TO\PROJECT\node_modules\terser-webpack-plugin\dist\index.js:366:38
DEV_MODE=dev
に戻すと先ほどと同じように問題なく動作。上記でこのフラグが関係するのは mode
と terser-webpack-plugin
の drop_console
の2箇所なので、そのどちらかだろうとアタリを付けます。
試しに drop_console
を常に false
としましたが、 DEV_MODE=prod
でエラーは再現しました。
となると、 mode
の方ということになります。
ここでエラー文で検索すると、以下の Issues を発見。 terser-webpack-plugin
本家のリポジトリです。
発生個所も含めてエラー文が同じです。
- TypeError: Cannot read property ‘javascript’ of undefined · Issue #335 · webpack-contrib/terser-webpack-plugin
- TypeError: Cannot read property ‘javascript’ of undefined ・ Issue #335 ・ webpack-contrib/terser-webpack-plugin
別の方のコメントを見ると、原因は以下の模様。
- terser-webpack-plugin 5 は Webpack 4 とは互換性がない
webpack-stream
の内部で使用している Webpack がバージョン 4 系
yep, we are working on it, release with fix will be today/tomorrow
TypeError: Cannot read property ‘javascript’ of undefined ・ Issue #335 ・ webpack-contrib/terser-webpack-plugin (2020/10/16日 22:04 JST)
わりとタイムリーなものを踏んでしまったようなので、 fixed されるのを待つ感じですかね……。