webpack踩坑--webpack 2.x升級至4.x

一.安裝webpack-cli,webpack@4.26.1

1.npm install webpack-cli -Djavascript

2.npm install webpack@4.26.1 -Dcss

二.踩坑

執行npm run dev報錯html

1./Users/lily/ForWork/forBMSys/bm-fe/node_modules/html-webpack-plugin/lib/compiler.js:81vue

var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
^
java

TypeError: compilation.mainTemplate.applyPluginsWaterfall is not a functionnode

 解決方案:1).npm install webpack-contrib/html-webpack-plugin -D 網上大多數是這個答案,可是我這裏執行不通,每次都報錯。暫時沒有找到緣由。webpack

    2).npm i -–save-dev html-webpack-plugin@next 
2./Users/lily/ForWork/forBMSys/bm-fe/node_modules/webpack/lib/webpack.js:185git

throw new RemovedPluginError(errorMessage);
^
github

Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.web

解決方案:

npm install --save-dev uglifyjs-webpack-plugin
webpack.dev.conf.js配置
var UglifyJsPlugin = require('uglifyjs-webpack-plugin')
optimization: {
minimizer: [
new UglifyJsPlugin({
exclude: /\.min\.js$/,
cache: true,
parallel: true, // 開啓並行壓縮,充分利用cpu
sourceMap: false,
extractComments: false, // 移除註釋
uglifyOptions: {
compress: false
}
})
]
}

 3./Users/lily/ForWork/forBMSys/bm-fe/node_modules/webpack/lib/webpack.js:185

throw new RemovedPluginError(errorMessage);
^

Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.

 解決方案:

註釋掉CommonsChunkPlugin,webpack4自帶代碼分割功能,若是想要覆蓋默認設置,能夠添加:

optimization: {
splitChunks: {
cacheGroups: {
commons: { // 抽離本身寫的公共代碼
chunks: "async", // async針對異步加載的chunk作切割,initial針對初始chunk,all針對全部chunk。
name: "common", // 打包後的文件名,任意命名
minChunks: 2,//最小引用2次
minSize: 30000 // 只要超出30000字節就生成一個新包
},
vendor: { // 抽離第三方插件
test: /[\\/]node_modules[\\/]/, // 指定是node_modules下的第三方包
chunks: 'initial',
name: 'vendor', // 打包後的文件名,任意命名
priority: 10 // 設置優先級,防止和自定義的公共代碼提取時被覆蓋,不進行打包
},
}
},
// runtimeChunk: true // 持久緩存moduleID,ChunkID須要HashedModuleIdsPlugin等插件解決
},

 注意:同時去掉 extract-text-webpack-plugin 插件的使用

4.cannot read property 'eslint' of undefined

解決方案:

1)網上查了不少,都讓使用LoaderOptionsPlugin方案,可是我這邊添加以後,並無任何效果依然報錯

plugins: [new webpack.LoaderOptionsPlugin({ options: {} }),],

2)升級eslint-loader,升級 eslint-loader to ^2.0.0. 因而有了第5個錯

5.ERROR in ./src/index.js

Module build failed (from ./node_modules/eslint-loader/index.js):
Error: eslint-plugin-html error: It seems that eslint is not loaded. If you think it is a bug, please file a report at https://github.com/BenoitZugmeyer/eslint-plugin-html/issues

解決方案:

eslint4只支持eslint-plugin-html V3 ,把eslint-plugin-html升級便可解決

https://github.com/BenoitZugmeyer/eslint-plugin-html/issues/60

6.ERROR in ./src/components/views/remote-dispatch/remote-car-sku-options/view/RemoteCarSkuOptionsCreate.vue?vue&type=style&index=0&id=a8deb48e&lang=scss&scoped=true& (./node_modules/vue-loader/lib??vue-loader-options!./src/components/views/remote-dispatch/remote-car-sku-options/view/RemoteCarSkuOptionsCreate.vue?vue&type=style&index=0&id=a8deb48e&lang=scss&scoped=true&) 99:0

Module parse failed: Unexpected token (99:0)
You may need an appropriate loader to handle this file type.
|
|
> .remote {
| padding: 20px;
| margin-top: 25px;

解決方案:

添加了file-loader就能夠了 

須要注意的是 MiniCssExtractPlugin.loader 和 style-loader 因爲某種緣由不能共存。

 7.代碼運行的時候,報錯,

error in ./src/components/views/workbench/designated-driving/view-customer/task-check/task-check.vue?vue&type=style&index=0&lang=css&

Syntax Error: NonErrorEmittedError: (Emitted value instead of an instance of Error) CssSyntaxError: /Users/lily/ForWork/forBMSys/bm-fe/src/components/views/workbench/designated-driving/view-customer/task-check/task-check.vue:1:1: Unknown word

> 1 | exports = module.exports = require("../../../../../../../node_modules/css-loader/lib/css-base.js")();
| ^
2 | // imports
3 |

@ ./node_modules/vue-style-loader!./node_modules/css-loader!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/css-loader??ref--8-1!./node_modules/vue-loader/lib??vue-loader-options!./src/components/views/workbench/designated-driving/view-customer/task-check/task-check.vue?vue&type=style&index=0&lang=css& 4:14-348 13:3-17:5 14:22-356

網上查的資料,大概兩種解決方案,1.css-loader,style-loader順序錯誤 2.刪除css,less配置 第一種已排除,實行第二種,可行。可是build的時候又會報第6個(上一條)錯誤

 

8.Error: Plugin could not be registered at 'html-webpack-plugin-after-emit'. Hook was not found.

BREAKING CHANGE: There need to exist a hook at 'this.hooks'. To create a compatibility layer for this hook, hook into 'this._pluginCompat'.
at Compilation.plugin (/Users/lily/ForWork/forBMSys/bm-fe/node_modules/tapable/lib/Tapable.js:69:9)
at Compilation.deprecated [as plugin] (internal/util.js:53:15)
at /Users/lily/ForWork/forBMSys/bm-fe/build/dev-server.js:38:15

解決方案:

場景:項目運行起來後,一旦作出更改,保存後,便會報出該錯
緣由:這個錯誤是html-webpack-plugin和webpack4兼容問題致使,更改html-webpack-plugin版本便可,3.0.4,3.0.6均可以,排除2.28.0,3.2.0,其餘版本尚未嘗試

---------webpack升級完成以後的分割線-----------

9.這是webpack升級爲4.0以後,項目迭代需求時遇到的問題

node_modules/html-webpack-plugin/node_modules/toposort/index.js:29
throw new Error('Cyclic dependency: '+JSON.stringify(node))

google上查都說是html-webpack-plugin的issue,參考 https://github.com/jantimon/html-webpack-plugin/issues/870 ,

更新html-webpack-plugin版本 以及安裝toposort 1.0.4版本 更新完以後貌似仍是報錯

後來在百度上查到一篇 說是webpack4打包vue2的bug https://blog.csdn.net/alanfancy/article/details/84023940

這才發現,原來是我webpack本地配置的HtmlWebpackPlugin沒有設置chunksSortMode: 'none' 至此問題解決

三.優化

1.html-webpack-plugin

npm i --save-dev html-webpack-plugin@next

plugins:[

new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'none'
}),
]

2.mini-css-extract-plugin 拆分css

它與extract-text-webpack-plugin最大的區別是:它在code spliting的時候會將原先內聯寫在每個 js chunk bundle的 css,單獨拆成了一個個 css 文件

rules: [
{
test: /\.css$/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
'css-loader'
]
},
{
test: /\.less$/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
'css-loader',
'less-loader'
]
},
...
]

3.optimize-css-assets-webpack-plugin 壓縮css 優化代碼

optimization: {
  minimizer: [new OptimizeCSSAssetsPlugin()]; }

4.熱更新速度 babel-plugin-dynamic-import-node

 1)首先在package.json中增長BABEL_ENV
"dev": "BABEL_ENV=development webpack-dev-server XXXX"
package.jsonBABEL_ENV

  2)在.babelrc只能加入babel-plugin-dynamic-import-node這個plugins,並讓它只有在development模式中才生效。

  {
    "env": {   「development": {   "plugins": ["dynamic-import-node"]    }   }     }

5.清除每次編譯後dist目錄重複文件 clean-webpack-plugin

 const CleanWebpackPlugin = require('clean-webpack-plugin');

plugins:[]
new CleanWebpackPlugin(['dist']),//實例化,參數爲目錄

6.代碼分割splitChunks

optimization: {
splitChunks: {
cacheGroups: {
elementUI: {
name: "chunk-elementUI", // 單獨將 elementUI 拆包
priority: 20, // 權重要大於 libs 和 app 否則會被打包進 libs 或者 app
test: /[\\/]node_modules[\\/]element-ui[\\/]/
},
libs: {
name: "chunk-libs",
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: "initial" // 只打包初始時依賴的第三方
},
commons: { // 抽離本身寫的公共代碼
chunks: "async", // async針對異步加載的chunk作切割,initial針對初始chunk,all針對全部chunk。
name: "common", // 打包後的文件名,任意命名
test: /[\\/]src[\\/]components[\\/]pages/,
minChunks: 3,//最小引用2次
minSize: 30000 // 只要超出30000字節就生成一個新包
},
}
},
runtimeChunk: {
name: "manifest"
},
minimizer: [new OptimizeCSSAssetsPlugin()]
}

7.externals分離第三方庫,cdn引入第三方資源

1)index.html中,引入第三方類庫 如:<script src="//cdn.bootcss.com/echarts/4.1.0/echarts.min.js"></script>

2) webpack.conf.js中配置externals 如

module.exports = {
  ...
  externals:{echarts: 'echarts'}
  ...
}

8.lodash按需加載

  點此查看個人另外一篇筆記 

踩坑繼續中,若是有人看到,歡迎隨時交流----

相關文章
相關標籤/搜索