优化原因
在没有使用cdn加速之前打包后数据如下,可以看出element-ui、vue、vuex、vue-router这些依赖都打进chunk-vendors.js中导致体积很大,假设再来很多依赖项是不是更大,同时也会影响单页面应用首屏加载速度,所以这里采用一种打包优化手段之一来分离依赖项。
查看依赖版本
首先项目中需要使用依赖项,我这里项目中打算将element-ui、vue、vuex、vue-router这些依赖项进行分离,记录依赖版本方便后面使用。
依赖名称 | 依赖版本 |
---|---|
vue | 2.6.11 |
vue-router | 3.2.0 |
vuex | 3.4.0 |
element-ui | 2.15.9 |
查看依赖引用
在main.js中可以看到这些依赖被引用。
在项目中开发环境和生成环境一些配置是不同的,所以这里截图方便后面理解。
配置开发环境和生产环境
在上面我们已经看到main.js中如何引用依赖,现在我们需要做一些改动在main.js改为main-dev.js作为我们的开发环境,然后在同级目录下创建一个新的文件叫main-prod.js作为我们的生产环境,实际开发中开发环境(main-dev.js)和生产环境(main-prod.js)配置存在不同。
开发环境入口 - main-dev.js
// 这是给ElementUI组件库组件设置默认参数
Vue.use(ElementUI, { size: 'small', zIndex: 3000 });
生产环境入口 - main-prod.js
// 这是给ElementUI组件库组件设置默认参数(cdn加速和生产环境配置有区别)
Vue.prototype.$ELEMENT = {
size: 'small',
zIndex: 3000
};
配置开发环境入口和生产环境入口
这里需要注意一下的是配置入口,因为默认入口文件只有一个main.js但是你给改成了main-dev.js而且还新增了一个main-prod.js,然后你运行项目或打包项目肯定报错,因为它去找main.js找不到啊,所以这里需要通过vue.config.js文件来指定生产环境和开发环境入口。
vue.config.js
// 判断是否是生产环境
const isProduction = process.env.NODE_ENV !== 'development';
module.exports = {
publicPath: './', // 不加这个可能会导致静态资源找不到的情况。
chainWebpack: config => {
config.when(isProduction, config => {
// 如果是生产环境,那么将main-prod.js作为入口文件(我这里是ts和js一样)。
config.entry('app').clear().add('./src/main-prod.ts');
});
config.when(!isProduction, config => {
// 如果是不是生产环境,那么将main-dev.js作为入口文件(我这里是ts和js一样).
config.entry('app').clear().add('./src/main-dev.ts');
});
}
};
配置CDN加速
完成上面环境配置已经成功一半啦,接下来就需要配置cdn加速相关的啦。
vue.config.js
这里需要说明一下,看下面的cdn加速链接中依赖的版本和上面查看依赖版本表格展示是不是一样的?肯定要一样啊不然出现依赖版本冲突问题怎么办。
关于externals属性告诉webpack需要排除的依赖名称和挂载在window上的对象属性名称,这里简单列出常用的表,如需要其它的可以插件依赖导出到window的对象名称,也可以面向百度查找对应的对象属性名称。
依赖名称 | 挂载在window上的对象属性名称 |
---|---|
vue | Vue |
vue-router | VueRouter |
vuex | Vuex |
lodash | _ |
element-ui | ELEMENT |
const isProduction = process.env.NODE_ENV !== 'development';
const cdn = {
externals: {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
"element-ui": "ELEMENT"
},
css: [
'https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.9/theme-chalk/index.min.css',
],
js: [
'https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js',
'https://cdn.jsdelivr.net/npm/vue-router@3.2.0/dist/vue-router.min.js',
'https://cdn.jsdelivr.net/npm/vuex@3.4.0/dist/vuex.min.js',
'https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.9/index.min.js'
]
};
module.exports = {
publicPath: './',
chainWebpack: config => {
config.when(isProduction, config => {
config.entry('app').clear().add('./src/main-prod.ts');
// 我们希望的是在生产环境下才进行cdn优化!!!这点理解很重要。
// 告诉webpack需要排除的依赖名称和挂载在window上的对象属性名称。
config.set('externals', cdn.externals);
// 这里的作用是在后面index.html页面中通过link,script标签加载这些cdn链接。
config.plugin('html').tap(args => {
args[0].cdn = cdn;
return args;
});
});
config.when(!isProduction, config => {
config.entry('app').clear().add('./src/main-dev.ts');
});
}
};
index.html
这里也需要说明一下,这个index.html页面的位置一般在public目录下。
下面的htmlWebpackPlugin.options.cdn对象是不是很眼熟,不就是我们通过vue.config.js中生产环境配置config.plugin(‘html’)加入的属性?真是一环扣一环呐。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<!-- 这里从cdn配置里面加载css文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" />
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
<% } %>
<!-- 这里从cdn配置里面加载js文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script" />
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<!-- 这里从cdn配置里面加载js文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
</body>
</html>
打包测试
完成以上步骤后,cdn打包优化就完成啦,现在运行打包测试一下。
下面打包数据和没有cdn优化的打包数据对比一下,是不是依赖项排除了?打包时间也变快了。
面试的时候是不是又多了一些底气了?