Spring Boot + npm + Geb で入力フォームを作ってテストする ( その54 )( webpack を 3.8.1 → 4.9.1 へバージョンアップする )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その53 )( Gradle を 3.5 → 4.6 へバージョンアップする ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- webpack を 3.8.1 → 4.9.1 へバージョンアップします。
参照したサイト・書籍
webpack/webpack-cli
https://github.com/webpack/webpack-cliwebpack-contrib/webpack-command
https://github.com/webpack-contrib/webpack-commandMigrating to Webpack 4 today
https://codeburst.io/migrating-to-webpack-4-today-d564b453a3bawebpack@4のmodeとminimize(UglifyJS)
https://numb86-tech.hatenablog.com/entry/2018/03/08/200527webpack-contrib/uglifyjs-webpack-plugin
https://github.com/webpack-contrib/uglifyjs-webpack-plugin
目次
- webpack を 3.8.1 → 4.9.1 へバージョンアップする
npm run build
コマンドを実行してみる- webpack-cli をインストールする
- 再び
npm run build
コマンドを実行してみる - uglifyjs-webpack-plugin を 1.2.2 → 1.2.5 へバージョンアップする
- webpack.config.js を変更する
- package.json を変更する
- cross-env をアンインストールする
- 動作確認
- webpack.config.js から optimization、devtool の設定を取り除くとどうなるのか?
手順
webpack を 3.8.1 → 4.9.1 へバージョンアップする
npm install --save-dev webpack@4.9.1
コマンドを実行します。
npm run build
コマンドを実行してみる
バージョンアップしただけで webpack.config.js は何も修正していない状態で npm run build
コマンドを実行してみます。
CLI が別のパッケージになったので webpack-cli か webpack-command をインストールするようメッセージが出力されました。webpack-cli と webpack-command の違いは webpack-command サイト内の Differences With webpack-cli に記述があります。
今回は webpack-cli をインストールします。
webpack-cli をインストールする
npm install --save-dev webpack-cli
コマンドを実行します。
再び npm run build
コマンドを実行してみる
再び npm run build
コマンドを実行してみます。
webpack 4 から追加された --mode
オプションを指定していないので、WARNING のメッセージが出力されました。
webpack 3 → 4 へのマイグレーション関連の記事を Web で調べて、以下の点を変更することにします。
- webpack を実行している npm scripts に
--mode
オプションを追加します。 - cross-env パッケージが不要になるのでアンインストールします。
- webpack 4 では
--mode development
が指定されている時には最適化処理が実行されず、--mode production
が指定されている時には最適化処理が実行されるようになったので、Uglify の設定を変更します。 - uglifyjs-webpack-plugin をインストールしなくても
--mode production
が指定されていると Uglify されるのですが、デフォルトの設定ではconsole.log()
が削除されないようなので、uglifyjs-webpack-plugin をインストールしたままにして独自に設定することにします。また uglifyjs-webpack-plugin を最新版にバージョンアップします。
uglifyjs-webpack-plugin を 1.2.2 → 1.2.5 へバージョンアップする
npm install --save-dev uglifyjs-webpack-plugin@1.2.5
コマンドを実行します。
webpack.config.js を変更する
webpack.config.js の以下の点を変更します。
const webpack = require("webpack"); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); // --mode オプションで指定された文字列を参照したい場合には argv.mode を参照する module.exports = (env, argv) => { return { entry: { "js/inquiry/input01": ["./src/main/assets/js/inquiry/input01.js"], "js/inquiry/input02": ["./src/main/assets/js/inquiry/input02.js"], "js/inquiry/input03": ["./src/main/assets/js/inquiry/input03.js"], "js/inquiry/confirm": ["./src/main/assets/js/inquiry/confirm.js"] }, output: { path: __dirname + "/src/main/resources/static", publicPath: "/", filename: "[name].js" }, resolve: { modules: [ "node_modules", "src/main/assets/js" ], alias: { jquery: "jquery" } }, module: { rules: [ { test: /\.js$/, exclude: [ /node_modules/, /jquery.autoKana.js$/ ], loader: "eslint-loader" } ] }, optimization: { minimizer: [ new UglifyJsPlugin({ uglifyOptions: { compress: true, ecma: 5, output: { comments: false }, compress: { dead_code: true, drop_console: true } }, sourceMap: false }) ] }, plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ], devtool: "inline-source-map" }; };
const isProduct = process.env.NODE_ENV === "product";
を削除します。--mode
オプションで指定されたモードを参照できるようにするために、module.exports = { ... };
→module.exports = (env, argv) => { return { ... }; };
に変更します。これでargv.mode
で--mode
オプションで指定された文字列を参照できるようになります。optimization: { ... }
を追加し、ここに UglifyJsPlugin の設定を記述します。optimization: { ... }
の設定は--mode development
の時には適用されず(Uglify や sourceMap出力が行われません)、--mode production
の時のみ適用されるようです(Uglify や sourceMap出力が行われます)。またecma: 6
にすると IE11 で入力画面2の郵便番号を入力してヒットした候補をドロップダウンリストに表示する機能が動作しなかったので、ecma: 5
にします。plugins: [ ... ]
から.concat(isProduct ? [new UglifyJsPlugin()] : []
を削除します。devtool: "inline-source-map"
は残します。残しておかないとソースが変わりすぎて Chrome で debug しにくそうに思えたからです。optimization: { ... }
で UglifyJsPlugin の設定も記述しておくと--mode production
の時に sourceMap が残りません。
ちなみに console.log()
が残ることを気にしなければ、optimization: { ... }
の設定がなくても --mode production
を指定すれば Uglify は行われます。
package.json を変更する
package.json の以下の点を変更します。
"scripts": { .......... "webpack:build": "webpack --mode production", "webpack:watch": "webpack --mode development --watch", .......... "build": "run-s clean:cssjs-dir postcss:build webpack:build" },
webpack:build
のコマンドをwebpack
→webpack --mode production
に変更します。webpack:watch
のコマンドをwebpack --watch
→webpack --mode development --watch
に変更します。build
のコマンドをcross-env NODE_ENV=product run-s ...
→run-s ...
に変更します。
cross-env をアンインストールする
npm uninstall --save-dev cross-env
コマンドを実行します。
動作確認
tomcat を起動した後、npm run springboot
コマンドを実行してみます。
生成された js ファイルを見るとファイルサイズが全て 700KB 以上あり、ファイルを開いてみても Uglify はされておらず、ソースはほぼそのまま残っています。
http://localhost:9080/inquiry/input/01/ にアクセスして入力画面1~3まで操作してみましたが、特に問題はありませんでした。
今度は npm run build
コマンドを実行してみます。
生成された js ファイルがほぼ 100KB 以下になり、ファイルを開いてみると Uglify されています。
http://localhost:8080/inquiry/input/01/ にアクセスして(ポート番号を 9080 → 8080 に変更して Tomcat に直接アクセスしています)入力画面1~3まで操作してみましたが、特に問題はありませんでした。
src/test/groovy/ksbysample/webapp/bootnpmgeb/web/inquiry/InquiryInputControllerTest.groovy の失敗するテストをコメントアウトした後、clean タスク実行 → Rebuild Project → build タスクを実行してみます。
BUILD SUCCESSFUL のメッセージが出力されました。
問題なさそうですので、このまま 4.9.1 を使います。書き終わった時には 4.10.2 までバージョンが上がっていましたが。。。
webpack.config.js から optimization、devtool の設定を取り除くとどうなるのか?
optimization、devtool の設定を書かない時の動作もメモしておきます。
webpack.config.js から optimization、devtool の設定を削除します。
.......... module: { rules: [ { test: /\.js$/, exclude: [ /node_modules/, /jquery.autoKana.js$/ ], loader: "eslint-loader" } ] }, plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ] }; };
まずは --mode development
である npm run springboot
を実行してみます。
optimization、devtool の設定を入れていた時は生成された js ファイルは 700KB以上ありましたが、今回は 300~400KB程度になりました。
生成された js ファイルを開いてみると、実行コードは改行コードが \r\n
に変換されて eval( ... );
で囲まれるようです。
Tomcat を起動してから、Chrome で http://localhost:8080/inquiry/input/01/ にアクセスして DevTools で input01.js を開いてみると、eval( ... );
のまま表示されて、これだと debug をどうやればよいのかちょっと分かりませんでした。
sourceMap もたぶん出力されていませんね。ファイルサイズが小さいのはその辺が理由でしょう。
次に --mode production
である npm run build
を実行してみます。
ファイルサイズは optimization、devtool の設定を入れていた時より数KBだけ大きいです。
生成された js ファイルを開いてみると、Uglify されていますがコメントが完全に削除されずに一部残っていました。
Tomcat を起動してから、Chrome で http://localhost:8080/inquiry/input/01/ にアクセスして動作確認してみましたが、IE11 でも入力画面2の郵便番号を入力してヒットした候補をドロップダウンリストに表示する機能が動作しましたし、他にも問題はありませんでした。
また console.log(...);
も入れていると削除されません(これは実際に書いて試してみました)。
今のところ、個人的には optimization、devtool の設定は書く方が好みですね。webpack 4 の設定がまだよく分かっていないだけかもしれませんが。
履歴
2018/06/02
初版発行。