项目 :vue.config.js
引入打包加速插件,引入打包进度插件
npm install hard-source-webpack-plugin
npm install progress-bar-webpack-plugin
npm install chalk
通过 externals 加载外部 CDN 资源
vue.config.js 的 chainWebpack 属性中,判断若打包环境为生产环境,则设置 externals配置打包时需跳过的资源
chainWebpack: config => {
if (IS_PROD) {
config.set('externals', {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios'
})
}
}
前往 public\index.html 文件中,把刚刚移除的资源通过链接的方式进行加载
<script src="https://cdn.staticfile.org/axios/0.21.4/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue-router/3.5.2/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.staticfile.org/vuex/3.6.2/vuex.min.js"></script>
优化前
优化后(后续项目越大,加载的第三方包越多,该优化越明显)
仅在开发环境下使用mock,利用tree shaking属性给打包瘦身
在 src\main.js 项目入口文件中,对mock数据的引入时,必须加上环境的判断 尽在开发环境下使用mock模块 vue-cli自身打包时即会利用webpack的tree shaking属性跳过使用过的代码
// 仅在开发环境时引入mock
if (process.env.NODE_ENV === "development") {
require("./request/mock/index.js"); // 模拟普通请求状态的mock
}
优化前
优化后
无需任何额外操作,整个mock模块消失不见
启用gzip
在vue.config.js 文件中的的 configureWebpack 配置中新增内容
但gzip除了本地配置以外还需要nginx进行配置支持的
在服务器的nginx配置中,在该项目的nginx匹配项中新增 gzip_static on 指令
验证开启成功与否,可以看看文件请求时Content-Encoding这个响应头
启用和不启用 gzip 的项目大小是有上多倍的压缩区别的,所以一定要配置!!
组件库按需引入
以引入elementUI为例,使用官网推荐的 babel-plugin-component 插件
npm install @babel/preset-env --save-dev
npm install babel-plugin-component --save-dev
在项目中新增 .babelrc 文件
{
"presets": [["@babel/preset-env", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "vvic-element-ui", // 组件库的名字
"styleLibraryName": "theme-chalk" // css目录的名字
}
]
]
}
然后在 main.js 项目的入口文件中实现对组件的按需引入
实际项目中,通常会把项目中使用范围较广的组件进行全局注入,如:
import {Message, Dialog, Button, Pagination, Select} from 'element-ui';
Vue.prototype.$message = Message;
Vue.use(Button);
Vue.use(Dialog);
Vue.use(Pagination);
Vue.use(Select);
然后后续各个地方中要引入其他组件库组件再各自 import {组件} from 'element-ui'即可
webpack分割代码块加载,大大提高页面加载速度
在 configureWebpack 配置中,新增下列属性,可实现公共代码块抽离,第三方库抽离,UI组件库抽离
使她们实现了独立的分包打包并用作为缓存
config.optimization = {
// 分割代码块
splitChunks: {
chunks: 'all', /**
* initial 入口 chunk,对于异步导入的文件不处理
async 异步 chunk,只对异步导入的文件处理
all 全部 chunk
*/
cacheGroups: {
//公用模块抽离
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial', // only package third parties that are initially dependent
},
//第三方库抽离
vendor: {
test: /node_modules/,
chunks: 'initial',
priority: 5,
reuseExistingChunk: true,
minSize: 0, //大于0个字节(模块的大小限制)
minChunks: 3, //在分割之前,这个代码块最小应该被引用的次数
//(最少复用过几次,只要命中一次,就把他作为单独的模块)
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?vvic-element-ui(.*)/, // in order to adapt to cnpm
},
},
},
};
动态加载路由
在 configureWebpack 配置中,新增下列属性,可实现对页面级别的代码抽离,加载对应页面时再加载对应的chunk.[hash].js
实例中执行的是如果是非本地环境,则使用普通hash,否则就使用contentHash
具体区别可参考:blog.csdn.net/weixin_3440…
// 加js的hash
config.output.filename = IS_PROD ? `vvic_[name].[contenthash].js` : `vvic_[name].[hash].js`;
config.output.chunkFilename = IS_PROD
? `vvic_[name].[contenthash].js`
: `vvic_[name].[hash].js`;
在vueRouter中路由配置中,对模块进行命名区分
这样子就能实现仅在 webpack 请求该模块的 chunk 时才会加载,即只有在用户访问时加载,然后被请求的模块和其应用的所有子模块都会分离到同一个异步
chunk 中