在使用webpack的extract-text-webpack-plugin插件提取單獨打包css文件時,報錯,說是這個插件要依賴webpack3的版本。
webpack4得使用mini-css-extract-plugin這個插件來單獨打包css。下面是使用方法:
將CSS提取為獨立的文件的插件,對每個包含css的js文件都會創建一個CSS文件,支持按需加載css和sourceMap
只能用在webpack4中,對比另一個插件 extract-text-webpack-plugin有點:
- 異步加載
- 不重復編譯,性能更好
- 更容易使用
- 只針對CSS
目前缺失功能,HMR。
安裝:
npm install --save-dev mini-css-extract-plugin
使用:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// 類似 webpackOptions.output里面的配置 可以忽略
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// 這里可以指定一個 publicPath
// 默認使用 webpackOptions.output中的publicPath
publicPath: '../'
},
},
'css-loader',
],
}
]
}
}
高級配置示例:
這個插件應該只用在 production 配置中,並且在loaders鏈中不使用 style-loader, 特別是在開發中使用HMR,因為這個插件暫時不支持HMR
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';
module.exports = {
plugins: [
new MiniCssExtractPlugin({
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',
],
}
]
}
}
production 階段進行壓縮
webpack5可能會內置CSS 壓縮器,webpack4需要自己使用壓縮器,可以使用 optimize-css-assets-webpack-plugin 插件。 設置 optimization.minimizer 覆蓋webpack默認提供的,確保也指定一個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,
sourcMap: true
}),
new OptimizeCSSAssetsPlugin({}),
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
}
}
將所有的CSS提取到一個文件中
和 extract-text-webpack-plugin 類似,可以使用 optimization.splitChunks.cacheGroups 將css提取到一個CSS中
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'
]
}
]
}
}
根據entry提取CSS
可以根據webpack 的entry name來提取CSS,這對你動態引入路由,卻想依據entry保存打包的CSS的情況十分有用。這也解決了ExtractTextPlugin中CSS重復的問題
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')
},
optimization: {
splitChunks: {
cacheGroups: {
fooStyles: {
name: 'foo',
test: (m,c,entry = 'foo') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true
},
barStyles: {
name: 'bar',
test: (m,c,entry = 'bar') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true
}
}
}
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
}
}
