參考文檔:
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。