参考文档:
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。
webpack4.x抽取css【extract-text-webpack-plugin与mini-css-extract-plugin】