[TOC]
webpack工程项目中配置第三方库的CDN,并做CDN容错
好处
- cdn可以利用缓存, 只需连接一次, 即有长久的缓存(只要不清除)
- 可以提升webpack打包速度,亲测打包速度 20s -> 13s (跟项目内第三方库数量有关)
场景举例
(假设内部平台有100个, 并且全部用了vue的cdn)
用户A只要登录过100个平台内的任意一个, 就会有vue的长久缓存, 在登录100个平台中的任意一个 都可以直接读vue的缓存
具体配置
1. 配webpack.config.js(根目录下)
...
const externals = { // 根据自己项目情况选择
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
axios: 'axios',
'view-design': 'iview',
'vue-i18n': 'VueI18n'
}
...
module.exports = (env) => {
...
externals,
...
}
2. 配置index.html(根目录下)
增加script标签,获取资源
- 根据上方配置的externals情况选择
// 找到当前项目的模板 index.html, 例如
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>xxx</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
// 这个需要改成: 如下, 增加 几个 script 标签 (根据上方配置的externals情况选择)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title></title>
<script title="cdn" src="https://xx-cdn.com/vue/vue-2.6.11.min.js" onerror="fallback('vue-2.6.11.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/vuex/vuex-3.1.2.min.js" onerror="fallback('vuex-3.1.2.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/vue-router/vue-router-3.1.6.min.js" onerror="fallback('vue-router-3.1.6.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/axios/axios-0.19.1.min.js" onerror="fallback('axios-0.19.1.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/view-ui/4.2.0/iview.min.js" onerror="fallback('iview-4.2.0.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/vue-i18n/8.22.1/vue-i18n.min.js" onerror="fallback('vue-i18n-8.22.1.min.js')"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
这样基本可以使用了,但还没完,因为CDN有可能会挂,虽然概率很低,但还是需要做容错
CDN容错
思路:当CDN挂掉的时候,我们选择自己内部备用的静态资源服务器,暂且域名叫:my-static.cn
难点:比如vue挂掉了,后续依赖vue的cdn资源,如:vue-router,也需要在执行一遍,否则拿不到vue对象
- 除了cdn资源要全部在执行一遍外,静态的js资源 如main.js也要重新执行一遍,因为里面也依赖vue
上代码: cdn-control.js
// 文件名:cdn-control.js
let fallbackRun = false;
const myServer = 'http://my-static.cn/cdn/'
// 自己内部备用的静态资源服务器
function fallback(fallbackUrl, local) {
fallbackUrl = local ? fallbackUrl : myServer + fallbackUrl;
let fallbackScript = document.createElement("script");
fallbackScript.src = fallbackUrl;
document.head.appendChild(fallbackScript);
if (!fallbackRun) {
fallbackRun = true;
window.onload = function (e) {
// head内的cdn比如iview是依赖vue的,如果vue的cdn挂了,此处需在刷新一遍cdn
for (let obj of document.head.children) {
if (obj.title === 'cdn') fallback(obj.src, 'local')
}
// body内的script有缓存后, 会比"容错的js文件"执行更快, 导致找不到vue, 直接挂掉
for (let obj of document.body.children) {
if (obj.tagName === 'SCRIPT') fallback(obj.src, 'local')
}
}
}
}
上面配置过的index.html需要引入cdn-control.js,并在之前的script标签内加上onerror属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title></title>
// "./cdn/cdn-control-min.js" cdn-control.js请自行手动加入项目,并压缩
+ <script title="cdn-control" src="./cdn/cdn-control-min.js"></script>
// 以下每个script都增加了 onerror 属性,如:onerror="fallback('vue-2.6.11.min.js')" (fallback函数是cdn-control.js里的)
<script title="cdn" src="https://xx-cdn.com/vue/vue-2.6.11.min.js" onerror="fallback('vue-2.6.11.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/vuex/vuex-3.1.2.min.js" onerror="fallback('vuex-3.1.2.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/vue-router/vue-router-3.1.6.min.js" onerror="fallback('vue-router-3.1.6.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/axios/axios-0.19.1.min.js" onerror="fallback('axios-0.19.1.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/view-ui/4.2.0/iview.min.js" onerror="fallback('iview-4.2.0.min.js')"></script>
<script title="cdn" src="https://xx-cdn.com/vue-i18n/8.22.1/vue-i18n.min.js" onerror="fallback('vue-i18n-8.22.1.min.js')"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
原创整理,如有误可留言。 如果有用,谢谢点赞~
性能优化合集快速入口: