webpack3.X 升级到 4.X
4.0的发布,让构建速度提升98%,包体积更小,配置,压缩,更现代化。具体请看
https://doc.webpack-china.org/guides/migrating/#-loader
- 需要升级nodejs到v6及以上版本(建议升级到10.13.0LTS版本)
- 如果要使用 webpack cli 命令,则需要单独再安装 webpack-cli
更新第三方依赖
这里会遇到很多错误提示,只要把相关的依赖升级到最新版本就好了。happypack的升级是比较容易忽略的,因为错误提示根本看不出来,看了很多网友分享的升级血泪史才发现的。。。
npm i webpack file-loader happypack less-loader webpack-dev-server webpack-merge -D
构建模式 mode: 包括development,production(这个升级方便了许多,官方做了许多默认设置,省去了不少工作)
参考文档: https://www.jianshu.com/p/80eaede27f37
module.exports = {
// ...
mode: 'production',
}
或者
"scripts": {
"prd": "webpack --config conf/webpack.prd.config.js -mode=production",
}
默认配置(图中红色部分)
支持json直接引入,不再需要json-loader,如果是其它json插件,则需要设置 type: 'javascript/auto'
module.exports = {
// ...
rules: [
{
test: /config\.json$/,
loader: 'special-loader',
type: 'javascript/auto',
options: {...}
}
]
};
production 模式默认开启压缩,不再需要设置 uglifyjs-webpack-plugin
optimization: {
minimize:true
}
移除module.loaders(webpack3就被废弃了,现在完全移除了,不再支持)
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig(entryFile)
}]
}
公共代码提取
- CommonsChunkPlugin 被移除,使用 optimization.splitChunks替代。
/*
* chunks: 表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all;
* minSize: 表示在压缩前的最小模块大小,默认为0;
* minChunks: 表示被引用次数,默认为1;
* maxAsyncRequests: 最大的按需(异步)加载次数,默认为1;
* maxInitialRequests: 最大的初始化加载次数,默认为1;
* name: 拆分出来块的名字(Chunk Names),默认由块名和hash值自动生成;
* cacheGroups: 缓存组。
*/
optimization: {
noEmitOnErrors: true,
splitChunks: {
chunks: 'all',
minSize: 0,
maxInitialRequests: Infinity,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
let bundleName = '';
let packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
packageName = packageName.replace('@', '');
switch (packageName) {
case 'yqb-mint-ui':
case 'mint-ui':
bundleName = 'mint';
break;
case 'vue-touch':
case 'vue-i18n':
case 'dayjs':
case 'axios':
case 'better-scroll':
bundleName = 'lib';
break;
default:
bundleName = 'vendor';
break;
}
return bundleName;
}
}
}
}
},
alias
别名:为了让后续引用的地方减少路径的复杂度。
pack项目配置 pack-projects-alias
DefinePlugin
DefinePlugin 允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和发布模式的构建允许不同的行为非常有用。如果在开发构建中,而不在发布构建中执行日志记录,则可以使用全局常量来决定是否记录日志。这就是 DefinePlugin 的用处,设置它,就可以忘记开发和发布构建的规则。
UglifyJsPlugin
现在也不需要使用这个plugin了,只需要使用optimization.minimize为true就行,production mode下面自动为true
mini-css-extract-plugin 替换为 extract-text-webpack-plugin
由于 extract-text-webpack-plugin 作者表示不再支持webpack4.3.0,未来 extract-text-webpack-plugin 将废弃,作者建议使用 mini-css-extract-plugin 插件.
[图片上传失败...(image-58a23e-1551018520188)]
问题1: mini-css-extract-plugin 的使用
这个需要注意区分开发环境使用vue-style-loader就好
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 开发环境使用vue-style-loader,方便热更新调试开发
rules:[
{
test: /\.css$/,
use: [process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
'css-loader']
}
]
问题2: 世纪大blocker:将css提取为一个文件
现状:webpack4默认会将css也分割成多个块,但是大多数情况下css总文件并不大,我们并不需要将css分的太细,有时候只需要一份bundle.css就够了。配置方法:
config.optimization.splitChunks.cacheGroups.styles = {
name: 'style',
// 一开始这里忘了匹配vue文件,总是会生成多个文件,需要注意
test: /\.(scss|css|less|vue)$/,
chunks: 'all',
priority: 30,
enforce: true
}
但是设置cacheGroup的同时还会生成style.js文件,这并不是我们需要的,我们期望只生成一份css文件,并且不需要这个多余的js文件,不过无奈。。这个问题依然存在,很多人因为这个问题而放弃了升级webpack4。
我们同样遇到了这个问题,因为旧插件项目引入的资源都是写死的,如果要引入这个style.js文件的话,改动较大,这是个悲伤的故事。。无法做到无感知升级。
看webpack说明预计要到webpack5才会解决这个问题。。。
该问题的相关issue见:
Single-file configuration emits JS assets in its own chunk group
[图片上传失败...(image-bb9379-1551018520188)]
[图片上传失败...(image-a52368-1551018520187)]
升级体验
升级后用碧桂园pamo项目打包测试了下打包效果,升级后的js资源包(压缩后)从1.2M降到了300多kb,简直就是amazing了。。。
不过开发环境的编译速度并没有什么明显的变化。
今天进一步优化了plugins-consumRecord消费记录模块,并对打包压缩后的js文件做了对比,记录一下
moment替换成dayjs的变化是很明显的,直接下降了180kb,压缩后的dayjs只有2kb,非常可观,而dayjs也足够满足业务需求。
external的设置,主要是因为插件项目或者h5项目引入的vue相关资源是从c999文件或者cdn加载,一定程度上减少了打包后的体积。
externals: {
zepto: 'Zepto',
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter'
},
常用的 webpack插件: https://segmentfault.com/a/1190000015355816
升级到Babel7
babel 7.X变化 ?
- 使用npm的scope包@balbel/xxx
注释: 什么是scope包?
https://www.npmjs.com.cn/misc/scope/
- 所有阶段预设state-x均已弃用,使用plugin代替
{ "plugins": [
// Stage 0
"@babel/plugin-proposal-function-bind",
// Stage 1
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-proposal-logical-assignment-operators", ["@babel/plugin-proposal-optional-chaining", { "loose": false }], ["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }],
["@babel/plugin-proposal-nullish-coalescing-operator", { "loose": false }],
"@babel/plugin-proposal-do-expressions",
// Stage 2
["@babel/plugin-proposal-decorators", { "legacy": true }], //解析装饰器 "@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions", //
Stage 3
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
["@babel/plugin-proposal-class-properties", { "loose": false }], "@babel/plugin-proposal-json-strings" ] }
- @babel/polyfill是@babel/runtime-corejs2的别名
{ "presets": [ ["@babel/preset-env", {"useBuiltIns": "usage"}] ], "plugins": [ ["@babel/plugin-transform-runtime",{"corejs": 2}] ] }
我们是如何升级的?
官方升级指南: https://babeljs.io/docs/en/v7-migration
"@babel/core": "^7.1.6",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-decorators": "^7.1.6",
"@babel/plugin-transform-runtime": "^7.1.0",
"@babel/preset-env": "^7.1.6",
"@babel/runtime": "^7.1.5",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"babel-plugin-dynamic-import-webpack": "^1.1.0",
"babel-plugin-import": "^1.11.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4",
网友评论