將css單獨打包成一個文件的插件,它為每個包含css的js文件都創建一個css文件。它支持css和sourceMaps的按需加載。
目前只有在webpack V4版本才支持使用該插件
和extract-text-webpack-plugin相比:
- 異步加載
- 無重復編譯,性能有所提升
- 用法簡單
- 之支持css分割
例子:
- 支持HMR
簡單的例子
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports={
plugins:[
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css"
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it use publicPath in webpackOptions.output
publicPath: '../'
}
},
"css-loader"
]
}
]
}
}
高級的配置
這個插件應該只在生產環境構建中使用,並且在loader鏈中不應該有style-loader,特別是我們在開發模式中使用HMR時。
下面是一個在開發模式中使用HMR並在生產環境構建的文件中提出出css樣式的示例。
(各個loader的配置根據你的需求進行自定義修改)
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== 'production'
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? '[name].css' : '[name].[hash].css',
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
})
],
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
}
]
}
}
生產環境最小化
等到webpack V5時,有可能會將css壓縮功能進行集成,但是在webpack V4,我們還需要手動使用optimize-css-assets-webpack-plugin來進行css的壓縮。配置wepack的optimization.minimizer選項來覆蓋webpack的默認配置。同時也要指定一個js壓縮器。
wepack.config.js
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports={
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
}
}
}
其他功能
使用預加載或內聯CSS
運行時代碼通過link 或 style標簽檢測已經添加的css,當在服務端注入css為了在服務端進行渲染時是非常有用的。link標簽的href屬性用來匹配被加載的css塊的URL,data-href屬性也可以在link和style標簽上使用,當使用內聯樣式的時候必須使用href.
提取所有的css到一個文件中
類似於 extract-text-webpack-plugin的作用,可以使用optimization.splitChunks.cacheGroups來將css提取到一個文件中
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true
}
}
}
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
}
}
根據webpack 的 entry 提取 css
還可以根據webpack entry提取CSS。如果動態導入路由,但希望根據條目將CSS綁定在一起,那么這一點尤其有用。這也防止了使用ExtractTextPlugin時出現的CSS復制問題。
webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
function recursiveIssuer(m) {
if (m.issuer) {
return recursiveIssuer(m.issuer);
} else if (m.name) {
return m.name;
} else {
return false;
}
}
module.exports = {
entry: {
foo: path.resolve(__dirname, 'src/foo'),
bar: path.resolve(__dirname, 'src/bar')
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
},
optimization:{
splitChunks:{
cacheGroups:{
fooStyles:{
fooStyles: {
name: 'foo',
test: (m,c,entry = 'foo') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true
}
}
}
}
}
}