MiniCssExtractPlugin 提取 CSS 到單個文件
目前示例中webpack使用css方式:
- css-loader:將js中的css內容解析
- 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()
]
},
// ...
}