webpack4.x抽取css【extract-text-webpack-plugin與mini-css-extract-plugin】
阿新 • • 發佈:2018-12-20
本文主要記錄筆者在使用webpack抽取css時遇到的一些問題。
專案的初始訴求是利用webpack來管理css(合併),並增加hash(效能優化),當前專案使用webpack版本為4.6.0。
開始選擇的外掛是extract-text-webpack-plugin,安裝命令如下:
sudo npm install extract-text-webpack-plugin
此時webpack配置檔案如下:
const path = require("path"); const htmlWebpackPlugin = require('html-webpack-plugin'); const cleanWebpackPlugin = require('clean-webpack-plugin'); const extractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: "./js/main.js", output: { path: path.resolve(__dirname, "build"), publicPath: "/build/", filename: "index.[chunkhash:8].js" }, module: { rules: [ { test: /\.js$/ , loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.css$/, use: extractTextPlugin.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', options: { url: false } } ] }) } ] }, devtool: 'inline-source-map', mode: 'development', plugins: [ new htmlWebpackPlugin({ filename: '../index.html', template: 'html/index.html', inject: 'body' }), new htmlWebpackPlugin({ filename: '../login.html', template: 'html/login.html', inject: 'body' }), new htmlWebpackPlugin({ filename: '../mail.html', template: 'html/mail.html', inject: 'body' }), new htmlWebpackPlugin({ filename: '../pinboard_copy_link.html', template: 'html/pinboard_copy_link.html', inject: 'body' }), new cleanWebpackPlugin(['build']), new extractTextPlugin({ filename: 'focus.index.css' }) ] };
但是構建時會報如下錯誤:
Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
檢查以後發現原因是extract-text-webpack-plugin預設安裝的版本是3.0.2,還不支援webpack的4.x版本。其實在初始安裝時就有告警提示,只是被忽略了:
接下來看一下extract-text-webpack-plugin有沒有方案來解決這個版本配套問題,百度以後瞭解到有extract-text-webpack-plugin有一個4.0的beta版本支援webpack4.x,把前面安裝的extract-text-webpack-plugin的3.0.2版本解除安裝, 重新安裝這個beta版本,安裝命令如下:
sudo npm install --save-dev [email protected]
此時可以正常構建了,也完成了第一個訴求——合併css,接下來是為css生成hash。
webpack配置檔案的最後一部分更新為:
new extractTextPlugin({
filename: 'focus.index.[contenthash:8].css'
})
但是構建時會報如下錯誤:
Error: Path variable [contenthash:8] not implemented in this context: focus.index.[contenthash:8].css
報錯截圖如下:
要用extract-text-webpack-plugin加hash看來是無解了,只能看看還有沒有其他外掛可以替代extract-text-webpack-plugin,又百度了一發,瞭解到可以用mini-css-extract-plugin替代extract-text-webpack-plugin,安裝命令如下:
sudo npm install mini-css-extract-plugin
webpack配置檔案更新如下(之前使用extract-text-webpack-plugin的部分已經註釋):
const path = require("path");
const htmlWebpackPlugin = require('html-webpack-plugin');
const cleanWebpackPlugin = require('clean-webpack-plugin');
// const extractTextPlugin = require('extract-text-webpack-plugin');
const miniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: "./js/main.js",
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/build/",
filename: "index.[chunkhash:8].js"
},
module: {
rules: [
{
test: /\.js$/ ,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
// use: extractTextPlugin.extract({
// fallback: 'style-loader',
// use: [
// {
// loader: 'css-loader',
// options: {
// url: false
// }
// }
// ]
// })
use: [
miniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false
}
}
]
}
]
},
devtool: 'inline-source-map',
mode: 'development',
plugins: [
new htmlWebpackPlugin({
filename: '../index.html',
template: 'html/index.html',
inject: 'body'
}),
new htmlWebpackPlugin({
filename: '../login.html',
template: 'html/login.html',
inject: 'body'
}),
new htmlWebpackPlugin({
filename: '../mail.html',
template: 'html/mail.html',
inject: 'body'
}),
new htmlWebpackPlugin({
filename: '../pinboard_copy_link.html',
template: 'html/pinboard_copy_link.html',
inject: 'body'
}),
new cleanWebpackPlugin(['build']),
// new extractTextPlugin({
// filename: 'focus.index.[contenthash:8].css'
// })
new miniCssExtractPlugin({
filename: 'focus.index.[contenthash:8].css'
})
]
};
最後終於構建成功了:
最後總結一下:
- 如果當前專案是webpack3.x版本,使用extract-text-webpack-plugin;
- 如果當前專案是webpack4.x版本(但已有extract-text-webpack-plugin配置),可以繼續用extract-text-webpack-plugin,但必須用對應的beta版本,且這個beta版本不支援生成hash;
- 如果當前專案是webpack4.x版本且是新專案,使用mini-css-extract-plugin。