logo头像

aferica

Vue-cli 3.0使用CDN引入依赖包和按需引入

本文于1714天之前发表,文中内容可能已经过时。

在Vue开发中过程中,我们会引入许多的依赖包,例如:路由管理vue-router、状态管理vuex和以及一些UI组件库,如ElementiView等,甚至需要添加报表。
在开发时我们不会感觉到太大问题,但是当要部署的时候,build结果却提示文件过大
如下图(这是一个使用Vue-cli 3.0新建的项目,没有添加任何业务代码,只是引入了Element组件):
20190429151550.png
可想而知,如果在引入其他组件,打包文件就会越来越大,严重影响首页加载速度

以下操作都是基于Vue-cli 3.0项目

下面,我会一步步优化打包体积:

一、按需加载

Element官方提供了安秀加载示例,下面我们按照官方教程实现一遍,查看效果

安装babel-plugin-component依赖包(使用Vue UI创建项目可忽略)

1
2
3
npm install babel-plugin-component -D
// or
yarn add babel-plugin-component --dev

安装vue-cli-plugin-element依赖包(使用Vue UI创建项目可忽略)

1
2
3
npm install vue-cli-plugin-element -D
// or
yarn add vue-cli-plugin-element --dev

覆盖babel.config.js文件(使用Vue UI创建项目可忽略)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.exports = {
"presets": [
"@vue/app"
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}

引入相关组件

为了方便日后管理维护,我们新建initEle.js来管理引入组件

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import {
Row,
Col,
Card,
Button,
Input,
Loading,
MessageBox,
Message,
Notification,
Popover,
Menu,
Submenu,
MenuItem,
MenuItemGroup,
Header,
Main
} from 'element-ui'

const initEle = Vue => {
Vue.prototype.$loading = Loading.service
Vue.prototype.$msgbox = MessageBox
Vue.prototype.$alert = MessageBox.alert
Vue.prototype.$confirm = MessageBox.confirm
Vue.prototype.$prompt = MessageBox.prompt
Vue.prototype.$notify = Notification
Vue.prototype.$message = Message
Vue.use(Row)
Vue.use(Col)
Vue.use(Card)
Vue.use(Button)
Vue.use(Input)
Vue.use(Popover)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
Vue.use(MenuItemGroup)
Vue.use(Header)
Vue.use(Main)
}

export default initEle

结果

打包后发现成效比较显著
20190429155433.png

问题

  • 按需加载是通过不引入使用的组件来减少提交的,这是就会有一个问题:
    如果是Element的重度用户,几乎引入了全部组件,那么按需引入的效果就不明显了
  • 即便不是重度用户,如果网站未使用Gzipped的话也显得较大

使用CDN引入依赖包

public/index.html文件中引入cdn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<head>
<!-- 引入样式 -->
<link href="https://cdn.bootcss.com/element-ui/2.7.2/theme-chalk/index.css" rel="stylesheet">
</head>
<body>
<noscript>
<strong>We're sorry but vue-template doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- 注意:vue引入开发模式不能使用压缩后的js文件, 即 **.min.js格式, 否则会导致调试工具无法使用 -->
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script src="//cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
<script src="//cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script>
<script src="//cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
<script src="//cdn.bootcss.com/element-ui/2.7.2/index.js"></script>
<!-- built files will be auto injected -->
</body>
...

修改vue.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
module.exports = {
// 添加cdn引用包
configureWebpack: {
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'axios':'axios',
'element-ui': 'ELEMENT'
}
},
// ...
}

覆盖babel.config.js文件

1
2
3
4
5
module.exports = {
"presets": [
"@vue/app"
]
}

结果

打包后发现成效显著
20190429161504.png

优点

  • 无需担心引入过多组件依旧导致包体积的问题
  • 使用公共可靠地cdn服务可以加速网站加载
  • 开发环境亦可以使用,配置完成后永绝后患
  • 几乎所有依赖包都可以通过此方式实现

缺点

  • 需要确保cdn服务的稳定和安全
  • 使用cdn引入时,cdn引入的名称有时不一致且不明显,导致引入不成功

开发环境使用cdn

通过上述配置,在开发环境也可以使用cdn,不过要注意:

如果需要使用vue devtools来调试,在引入vue的cdn是不能引入*.min.js压缩后的js,否则会导致无法使用调试

微信打赏

你的赞赏是对我最大的鼓励