本文主要记录笔者在使用webpack抽取css时遇到的一些问题。
参考文档:
https://www.npmjs.com/package/extract-text-webpack-plugin
https://www.npmjs.com/package/mini-css-extract-plugin
项目的初始诉求是利用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 extract-text-webpack-plugin@next
此时可以正常构建了,也完成了第一个诉求——合并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。