webpack4 升级
webpack4升级之坑
webpack4出来已经好久,看到之前的vue-cli项目还是基于"webpack": “^3.6.0”,所以参考了一些资料,对webpack3做了升级。
webpack版本升级
"webpack": "^4.29.6"
cnpm i 或者 npm i ,依赖安装,npm run dev 看下效果,出现一堆的错误。不难发现是webpack-dev-server 导致:
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
module.js:491
throw err;
^
Error: Cannot find module 'webpack/bin/config-yargs'
at Function.Module._resolveFilename (module.js:489:15)
at Function.Module._load (module.js:439:25)
at Module.require (module.js:517:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/Users/xumingxing/Desktop/h5-vue/node_modules/webpack-dev-server/bin/webpack-dev-server.js:54:1)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] dev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
紧接着,我们就应该继续升级webpack-dev-server ,我将其升级为最新版本,npm run dev 也出错了。主要是compilation.mainTemplate.applyPluginsWaterfall报错,查了资料是 html-webpack-plugin 版本不兼容导致。同样也可将其升级为最新版:
"webpack-dev-server": "^3.2.1",
//报错主要信息
...es/[email protected]1.4.1@punycode/punycode.js/Users/xumingxing/Desktop/h5-vue/node_modules/html-webpack-plugin/lib/compiler.js:81
var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
^
TypeError: compilation.mainTemplate.applyPluginsWaterfall is not a function
at /Users/xumingxing/Desktop/h5-vue/node_modules/html-webpack-plugin/lib/compiler.js:81:51
at compile (/Users/xumingxing/Desktop/h5-vue/node_modules/[email protected]4.29.6@webpack/lib/Compiler.js:306:11)
at hooks.afterCompile.callAsync.err
升级html-webpack-plugin
"html-webpack-plugin": "^3.2.0",
升级完成后,我们再继续npm run dev 看下效果:
Module build failed (from ./node_modules/vue-loader/index.js):
TypeError: Cannot read property 'vue' of undefined
at Object.module.exports (/Users/xumingxing/Desktop/h5-vue/node_modules/vue-loader/lib/loader.js:61:17)
@ ./src/main.js 4:0-24 13:16-19
@ multi ./node_modules/_webpack-dev-[email protected]3.2.1@webpack-dev-server/client?http://localhost:8081 (webpack)/hot/dev-server.js ./src/main.js
页面依旧报错,查询资料后是继续要升级vue-loader,这里将其升级为"15.7.0":
"vue-loader": "^15.7.0"
升级完成后,npm run dev ,又是一大堆错误:
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
94% after seal
ERROR Failed to compile with 2 errors 15:53:25
error in ./src/App.vue
Module build failed (from ./node_modules/vue-loader/index.js):
TypeError: Cannot read property 'vue' of undefined
at Object.module.exports (/Users/xumingxing/Desktop/h5-vue/node_modules/vue-loader/lib/loader.js:61:17)
@ ./src/main.js 4:0-24 13:16-19
@ multi ./node_modules/_webpack-dev-[email protected]3.2.1@webpack-dev-server/client?http://localhost:8081 (webpack)/hot/dev-server.js ./src/main.js
error in ./src/components/HelloWorld.vue
star:h5-vue xumingxing$ npm run dev
> h5-[email protected]1.0.0 dev /Users/xumingxing/Desktop/h5-vue
> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
94% after seal
ERROR Failed to compile with 5 errors 15:56:38
error in ./src/components/HelloWorld.vue
Module Error (from ./node_modules/_vue-[email protected]15.7.0@vue-loader/lib/index.js):
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
@ ./src/router/index.js 3:0-49 11:15-25
@ ./src/main.js
@ multi ./node_modules/_webpack-dev-[email protected]3.2.1@webpack-dev-server/client?http://localhost:8081 (webpack)/hot/dev-server.js ./src/main.js
error in ./src/App.vue?vue&type=style&index=0&lang=css&
Module parse failed: Unexpected character '#' (15:0)
You may need an appropriate loader to handle this file type.
|
|
> #app {
| font-family: 'Avenir', Helvetica, Arial, sans-serif;
| -webkit-font-smoothing: antialiased;
@ ./src/App.vue 4:0-63
@ ./src/main.js
@ multi ./node_modules/_webpack-dev-[email protected]3.2.1@webpack-dev-server/client?http://localhost:8081 (webpack)/hot/dev-server.js ./src/main.js
error in ./src/components/HelloWorld.vue?vue&type=template&id=469af010&scoped=true&
错误提示:vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config。这边的错误主要是vue-loader 比较新导致的,新版的vue-loader需要增加新的VueLoaderPlugin:
主要需要在webpack.dev.conf.js以及webpack.prod.conf.js 添加:
const VueLoaderPlugin = require(‘vue-loader/lib/plugin.js’)
并在plugins再实例化一下:
//...
const VueLoaderPlugin = require('vue-loader/lib/plugin')
//...
plugins: [
//....
new VueLoaderPlugin(),
//...
]
之前不小心写成了require(‘vue-loader’),系统报错了。写配置的同学需要注意下
loaderContext.emitError(new Error(
^
TypeError: loaderContext.emitError is not a function
看了一些资料说是webpack4需要制定打包的模式(mode),自己在npm run dev 的时候并未出现类似的提示,故未作配置。不过有兴趣的也可配置一下,在webpack.dev.conf.js以及webpack.prod.conf.js里添加一下mode:‘development’/mode:‘production’
const webpackConfig = merge(baseWebpackConfig, {
mode: 'production',
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
//...
})
npm run dev ,运行成功了,效果如下:
如果需要执行 npm run build,发现又有问题了,系统报错:
Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.
at Object.get [as CommonsChunkPlugin] (/Users/xumingxing/Desktop/h5-vue/node_modules/[email protected]4.29.6@webpack/lib/webpack.js:185:10)
at Object.<anonymous> (/Users/xumingxing/Desktop/h5-vue/build/webpack.prod.conf.js:85:25)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Module.require (module.js:517:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/Users/xumingxing/Desktop/h5-vue/build/build.js:12:23)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! h5-[email protected]1.0.0 build: `node build/build.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the h5-[email protected]1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
出错的原因是webpack4中 webpack.optimize.CommonsChunkPlugin 已经被弃用,需要使用新的配置 config.optimization.splitChunks。修改webpack.prod.conf.js。首先找到和CommonsChunkPlugin相关的代码,并全部注释。与plugins同级,插入optimization配置
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
})
optimization配置:
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: "commons",
chunks: "initial",
minChunks: 2
}
}
}
},
更改后,再重新执行npm run build ,又报错了:
Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
at Chunk.get (/Users/xumingxing/Desktop/h5-vue/node_modules/[email protected]4.29.6@webpack/lib/Chunk.js:849:9)
at /Users/xumingxing/Desktop/h5-vue/node_modules/_extract-text-webpack-[email protected]3.0.2@extract-text-webpack-plugin/dist/index.js:176:47
at Array.forEach (<anonymous>)
at /Users/xumingxing/Desktop/h5-vue/node_modules/_extract-text-webpack-[email protected]3.0.2@extract-text-webpack-plugin/dist/index.js:171:18
at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/xumingxing/Desktop/h5-vue/node_modules/[email protected]1.1.1@tapable/lib/HookCodeFactory.js:32:10), <anonymous>:7:1)
不难发现,Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead。上网查了下,解决这个问题方法较多。可以升级extract-text-webpack-plugin:
"extract-text-webpack-plugin": "^4.0.0-beta.0",
同样也是可以用 mini-css-extract-plugin进行处理,我这里就是用mini-css-extract-plugin进行处理。
本文升级成功后的demo下载地址:https://github.com/yzbyxmx/h5-vue.git