webpack二刷之五、生產環境優化(5.提取壓縮CSS)

MiniCssExtractPlugin 提取 CSS 到單個文件

目前示例中webpack使用css方式:

  1. css-loader:將js中的css內容解析
  2. style-loader:最終將css樣式通過<style>標籤方式注入到頁面中。

CSS內容還是存儲在JS文件中。

MiniCssExtractPlugin 插件可以將CSS內容從打包結果中提取出來,存放到文件中。

通過這個插件,就可以實現CSS模塊的按需加載。

因爲提取後生成了css文件,所以就不需要<style>標籤,而是直接通過<link>的方式引入。

所以使用MiniCssExtractPlugin,就不需要style-loader,而是使用插件提供的loader實現通過<link>標籤的方式注入。

安裝yarn add mini-css-extract-plugin --dev

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader', // 通過 style 標籤注入
          MiniCssExtractPlugin.loader, // 通過 link 標籤注入
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin()
  ]
}

打包後,就會在輸出目錄下,看到提取出來的css文件了,它的名稱使用的是導入它的模塊的名稱(可能是魔法註釋的名稱,可能是合併打包成一個文件)。

打包效果:

css模塊不會被包裹在函數中,作爲數組參數的元素被使用。

而是在主入口文件執行方法中,以<link>標籤+文件路徑的形式注入到html中。

建議:

如果樣式內容不是很多的話,提取到單個文件的效果不是很好。

建議CSS文件超過150kb左右,才考慮提取到單個文件中。

否則css嵌入到代碼中,減少一次請求,效果可能更好。

OptimizeCssAssetsWebpackPlugin 壓縮輸出的css文件

使用MiniCssExtractPlugin後,樣式就被提取到單獨的css文件中了。

前面說過,webpack在production模式下,會自動壓縮優化打包的結果。

但是單獨提取的css文件並沒有被壓縮。

這是因爲webpack內置的壓縮插件,僅僅支持JS文件的壓縮。

對於其他類型的文件壓縮,都需要額外的插件支持。

webpack推薦使用「optimize-css-assets-webpack-plugin」插件壓縮樣式文件。

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = {
  mode: 'none',
  output: {
    filename: '[name].bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader', // 通過 style 標籤注入
          MiniCssExtractPlugin.loader, // 通過 link 標籤注入
          'css-loader'
        ],
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
    }),
    new MiniCssExtractPlugin(),
    new OptimizeCssAssetsWebpackPlugin()
  ],
}

optimization.minimizer

webpack官方文檔介紹時並不是將 「OptimizeCssAssetsWebpackPlugin」 插件配置在「plugins」數組中。

而是配置在 「optimization.minimizer」 數組中。

原因是:

配置在「plugins」中,webpack就會在啓動時使用這個插件。

而配置在 「optimization.minimizer」 中,就只會在「optimization.minimize」這個特性開啓時使用。

所以webpack推薦,像壓縮類的插件,應該配置在「optimization.minimizer」數組中。

以便於通過「optimization.minimize」統一控制。(生產環境會默認開啓minimize)

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = {
  mode: 'none',
  output: {
    filename: '[name].bundle.js',
  },
  optimization: {
    minimize: true,
    minimizer: [
      new OptimizeCssAssetsWebpackPlugin()
    ]
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader', // 通過 style 標籤注入
          MiniCssExtractPlugin.loader, // 通過 link 標籤注入
          'css-loader'
        ],
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
    }),
    new MiniCssExtractPlugin(),
    // new OptimizeCssAssetsWebpackPlugin()
  ],
}

然而這樣配置會導致JS不會被壓縮。

原因是webpack認爲,如果配置了minimizer,就表示開發者在自定以壓縮插件。

內部的JS壓縮器就會被覆蓋掉。所以這裏還需要手動將它添加回來。

webpack內部使用的JS壓縮器是「terser-webpack-plugin」。

注意:手動添加需要安裝這個插件才能使用。

// 只展示了添加的代碼
const TerserWebpackPlugin = require('terser-webpack-plugin')
module.exports = {
  // ...
  optimization: {
    minimize: true,
    minimizer: [
      new TerserWebpackPlugin(),
      new OptimizeCssAssetsWebpackPlugin()
    ]
  },
  // ...
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章