软件包升级
1 2 3 4 5 6 7 8 9 10
| "html-webpack-plugin": "^3.2.0", "vue-loader": "^15.9.0", "webpack": "^4.42.0", "copy-webpack-plugin": "^5.1.1", "file-loader": "^5.1.0", "inline-manifest-webpack-plugin": "^4.0.2", "svg-sprite-loader": "^4.2.1", "terser-webpack-plugin": "^2.3.5", "webpack-dev-middleware": "^3.7.2", "webpack-dev-server": "^3.10.3"
|
CommonChunksPlugin升级
Webpack 4 兼容性升级,Webpack4 不再支持 CommonChunksPlugin这个插件了,使用了新的splitChunks
重要的区别是
- 新的配置放在了optimization下面了,不再放在plugins里
- 配置cacheGroups的逻辑和原来CommonChunksPlugin不完全一样,需要去理解文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| optimization: { splitChunks: { cacheGroups: { uilib: { name:'uilib', chunks: 'initial', test: /node_modules.\_?(mint-ui|cube-ui)/, priority: -10, }, vendor: { name:'vendor', chunks: 'initial', test: /node_modules./, priority: -20, } } }, runtimeChunk: { name: "manifest" }, },
|
UglifyJSPlugin升级
Webpack 4 兼容性升级,Webpack4 不再支持UglifyJSPlugin,需要改为TerserPlugin
重要的区别是
- UglifyJSPlugin 不支持ES6了,所以用TerserPlugin
- TerserPlugin要放在 .optimization.minimizer 下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| config.optimization.minimizer.push(new TerserPlugin({ terserOptions: { output: { comments: false, }, compress: { collapse_vars: true, reduce_vars: true }, warnings: false, }, parallel: true, sourceMap: false, cache: true, }));
|
Webpack 4 添加mode
Webpack 4 兼容性升级,需要设置mode
正式包就用 production
1 2 3 4 5 6 7 8 9
| const config = merge(baseConfig, { name: plugin, mode: 'production', output: { path: urls.moduleDistPath, filename: "[name].[chunkhash:8].bundle.js", chunkFilename: "[name].[chunkhash:8].bundle.js", } })
|
调试时用 development
1
| this.config.mode = 'development';
|
Vue-Loader 升级
Vue-Loader 15 兼容性升级,需要显式导入 VueLoaderPlugin
必须在处理html之前,设置好VueLoaderPlugin去解析vue文件。https://vue-loader.vuejs.org/migrating.html#a-plugin-is-now-required
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template: htmlPath, inject: true, chunks: ['uilib', 'vendor', 'manifest', 'app'] }), new webpack.HashedModuleIdsPlugin(), new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "windows.jQuery": "jquery" }) ],
|
Vue-Loader 15 兼容性升级,必须显式的指定less loader
相关文档 https://vue-loader.vuejs.org/migrating.html#loader-inference
1 2 3 4 5 6 7 8 9 10 11 12 13
| { test: /\.less$/, use: [{ loader: "style-loader" },{ loader: "css-loader", options: { esModule: false, }, }, { loader: "less-loader" }] }
|
Vue-Loader 14 兼容性升级,默认输入ES6 module,并且移除了esModule:false 支持
解决方案:各个Loader需要兼容esModule
针对Vue文件
对于Vue-Loader生成的 文件,需要静态替换源代码, 所以自己编写require替换插件 compatible-es-module.js 如下:
目的是把 require(‘./xx.vue’) 替换为 require(‘./xx.vue’).default。
1 2 3 4 5 6 7 8
| module.exports = function(content) { return content.replace( new RegExp(/require\(('|")(.*)[/\w\.]+\.vue(.*)('|")\)(\.default)?/,'g'), function(res) { const result = /(\.default)$/.test(res)? res: (res + '.default'); return result; }); };
|
当Vue文件引用Vue文件时:
1 2 3 4 5
| test: /\.vue$/, use: [ 'vue-loader', path.resolve(path.join(urls.localNodeModulePath, 'compatible-es-module')), ]
|
针对JS文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| test: /\.js$/, use: [ { loader: 'babel-loader', options: { presets: ['es2015', 'stage-2'], comments: true, cacheDirectory: true } },{ loader: path.resolve(path.join(urls.localNodeModulePath, 'compatible-es-module')), } ]
|
针对CSS文件
处理css esModule
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| { test: /\.styl$|\.stylus$/, use: [ "style-loader", { loader: "css-loader", options: { esModule: false, }, }, 'stylus-loader' ] }, { test: /\.css$/, use: [ "style-loader", { loader: "css-loader", options: { esModule: false, }, }, "postcss-loader" ] },
|
针对图片文件
处理图片 esModule
1 2 3 4 5 6 7 8 9 10 11 12 13
| { test: /\.(png|jpg|gif|svg)$/, use: [ { loader: 'url-loader', options: { limit: 8192, name: 'images/[hash:7].[name].[ext]', esModule: false, } } ] },
|
针对字体文件
处理字体 esModule
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { test: /\.ttf$/, loader: 'url-loader', options: { name: 'font/[name].[ext]', esModule: false, } }, { test: /\.(eot|svg|woff|woff2)(\?\S*)?$/, loader: 'file-loader', options: { esModule: false, }, }]
|
升级后注意
webpack4 升级后。vue-loader 更改了模块导出格式。
从原来的CommonJS标准改为了ES2015 Module。ES2015 Module的关键字是import,CommonJS的关键字是require,而import 是JS语言的标准,require是社区的标准。
所以建议
尽量优先用 import。在确定要用require的时候用require。
需要require 一个vue 文件时,请务必加上后缀(为了兼容自定义的 compatible-es-module.js 插件)
比如要require Test.vue 不要写成Vue.component(‘test’, require(‘./Test’))
请写成 Vue.component(‘test’, require(‘./Test.vue’))