2022-05-01

Larave 8 使用 terser-webpack-plugin 在 webpack 時用 esbuild 進行 minify

用 Laravel 的朋友們應該都知道,無論用 vue、react 或單純 js、css 都可以經由 webpack.mix.js 來打包成 webpack 或單純就是把上述的 code 集收起來…不過,開發到一定時日或用的套件越來越多時,這個 pack …就會越來越肥大。

雖說在發佈成 production 時會自帶 minify,但不知道有沒有和在下一樣的,因為案子是多 pg 合作,pg 有全端或單後端或單前端…前端目前有分 js + jq 和 js + vue3 的,在下是全端,在前端雖會用 vue,但目前來說還是 js + jq 是主力;但目前案子很常是 npm run watch 或 npm run dev 出來的 vue 是可以運作的,但發佈成 npm run prod 後就壞掉了…所以案子都是以 development 的方式在運行…但,匯出來的 js 頗肥呀。

在下原本用來解決這個的方式是在 packages.json 的 scripts 多寫一個用 uglifyjs 來做 minify 的指令來做,可以看看

uglifyjs public/js/app.js -o public/js/app.min.js -c -m --source-map && uglifyjs public/js/vue.js -o public/js/vue.min.js -c -m --source-map

之後接觸 esbuild 這強大的工具之後,就利用這篇改寫了上述用來 minify 的指令,效果是不錯,但…因為強大的懶惰基因就一直讓我在想「如果在 npm run watch 時就可以同時把 app.js, vue.js minify 那不就更好」,所以就開始找工具了…後來果然網路是強大的…

事前準備,專案的 packages.json 請安裝下列套件

  • css-minimizer-webpack-plugin
  • terser-webpack-plug
第一個是用來做 css minify 的,第二個是用來做 js minify 的

接著,請修改專案的 webpack.mix.js

首先,先載入上述兩個套件
const mix = require('laravel-mix'); // 這是 webpack.mix.js 本來就有的
const twp = require('terser-webpack-plugin'); // add this, 名稱可自取
const cmwp = require('css-minimizer-webpack-plugin'); // add this, 名稱可自取

接著,請在原本的 mix 的載體增加 webpackConfig() 的方式,然後進行設定,大至如下

 mix
  .js('resources/js/app.js', 'public/js')
  .js('resources/js/vue.js', 'public/js')
  .vue()
  .sass('resources/sass/app.scss', 'public/css')
  .postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
  ])
  .webpackConfig({
    resolve: {
      extensions: ['.js', '.jsx', '.scss', '.css'],
      modules: ['node_modules']
    },
    stats: 'errors-only',
    watchOptions: {
      ignored: /node_modules/, // 無視 node_modules 下的
    },
    optimization: {
      minimize: true,
      minimizer: [
        new twp({ // terser-webpack-plug 的設定
          extractComments: false, // 不匯出 xxx.License.js
          terserOptions: {
            mangle: true, // 應該是類似進行 uglify 那種把名稱做 mask
            compress: {
              drop_console: true, // 移除 console.*
              drop_debugger: true, // 移除 debugger
            },
            output: {
              comments: false, // 不輸出註解
              beautify: false, // 不進行排版,如果你不做 minify 的話可以啟用
            },
          },
        }),
        new cmwp({ // css-minimizer-webpack-plugin 的設定
          test: /.s?css$/i, // 以 .scss, .css 為主
          minimizerOptions: {
            preset: [
              "default",
              {
                discardComments: { removeAll: true }, // 不輸出註解
              },
            ],
          },
        }),
      ],
    },
  });

// if (!mix.inProduction()) { // 如果 mix 不是以 npm run prod 載入時,會改以下的設定
//   mix.webpackConfig({ devtool: 'eval-cheap-module-source-map' });
// }

這樣,在 npm run watch 就能順便 minify 了…讚!!!!

我打算在下個專案的 Laravel 中加入,目前的專案先保留舊方式 

沒有留言: