webpackの移行先として、下記の図の通り速度を重視しesbuildが検討されることも多いかと思いますが、
webpackを使いつつ一部のbuildをesbuildに置き換えるようなことができるesbuild-loader
というライブラリがあるようなので試してみました。
前提
いかのようにjsをbabel-loader、tsをts-loaderでbuildするような構成のものを、開発環境でだけ、それぞれesbuildでbuildするようにしてみます。 ※環境別のconfigの切り替えにはwebpack-mergeを利用しています
module: { rules: [ { test: /\.(scss|css)/, use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], }, { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader", }, }, { test: /\.ts$/, exclude: /node_modules/, loader: "ts-loader", options: { // /vueをtypescriptとして扱う appendTsSuffixTo: [/\.vue/], transpileOnly: true, }, }, { test: /\.vue/, loader: "vue-loader", options: { loaders: { scss: "vue-style-loader!css-loader!sass-loader", }, }, }, { test: /\.(png|jpe?g|gif)$/i, type: "asset/resource", }, ], },
webpack configを修正してesbuildに置き換える
以下のようにbabel-loaderとts-loaderをesbuildでのbuild設定で上書きしてあげるだけで大丈夫でした!
process.env.NODE_ENV = "development"; const { merge } = require("webpack-merge"); const common = require("../../webpack.common.js"); const babelLoaderIndex = common.module.rules.findIndex((rule) => rule.use?.loader == "babel-loader"); const tsLoaderIndex = common.module.rules.findIndex((rule) => rule.use?.loader == "ts-loader"); common.module.rules[babelLoaderIndex] = { test: /\.js$/, exclude: /node_modules/, use: { loader: "esbuild-loader", options: { loader: "js", target: "es2015", sourcemap: true }, }, }; common.module.rules[tsLoaderIndex] = { test: /\.ts$/, exclude: /node_modules/, use: { loader: "esbuild-loader", options: { loader: "ts", target: "es2015", sourcemap: true }, }, }; module.exports = merge(common, { mode: process.env.NODE_ENV, });
改善結果
個人のwebサービス(対象ファイル70ファイル程度)を試しにesbuild-loader
に差し替えてみたところ0.5秒ほど早くなりました🚀
この程度のファイル数でも速度が変わったので大規模サービスの場合には、より明確な差が出そう。
// ts-loader and babel-loader: 最速・最遅を除いた平均 3.953 ✨ Done in 3.69s. ✨ Done in 3.85s. ✨ Done in 3.93s. ✨ Done in 4.08s. ✨ Done in 4.31s. // esbuild-loader: 最速・最遅を除いた平均 3.4833 ✨ Done in 3.38s. ✨ Done in 3.47s. ✨ Done in 3.49s. ✨ Done in 3.49s. ✨ Done in 3.59s.
esbuild-loaderはwebpack v4でもテスト実行してるので動きそうですね。
https://github.com/privatenumber/esbuild-loader/blob/v2.19.0/test/loader.test.ts#L12-L15
おわりに
webpackをesbuildに移行せずに一部差し替えてお手軽に高速化できるのは良いですね✨