目的
webpack 默认会将使用的模块全部打包成本地文件,除了使用代码拆分(code split)优化打包,也可以使用 CDN,减少打包的内容,享受 CDN 缓存的优势。
webpack 的 externals
配置可以将指定的第三方库移除打包清单,减少打包时间和体积,但又不影响使用模块化的方式导入第三方库,例如 import
。
例如,使用 CDN 引入 element-ui,依然使用 import ElementUI from 'element-ui'
导入。
CDN 引入 element-ui
以 Vue CLI 创建的项目中使用 element-ui 为例。
配置 vue.config.js
:
// vue.config.js
/** @type {import('@vue/cli-service').ProjectOptions} */
module.exports = {
chainWebpack: webpackConfig => {
webpackConfig.externals({
// [import模块名]: [CDN引入的全局变量名]
'element-ui': 'ELEMENT'
})
}
}
在模板文件 /public/index.html
中添加 CDN 引入:
<!DOCTYPE html>
<html lang="en">
<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>
</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 -->
<script src="https://unpkg.com/element-ui@2.14.1/lib/index.js"></script>
</body>
</html>
Vue 注册 ElementUI:
// /src/main.js
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
npm run build
打包:
CDN 挂了怎么办
最好的办法是自己部署 CDN,或者购买CDN服务。
如果使用第三方 CDN,可以在项目本地存放一份文件,当页面加载时,判断 CDN 引入创建的全局变量是否存在,如果不存在则加载本地文件。
<script src="https://unpkg.com/2element-ui@2.14.1/lib/index.js"></script>
<script>
if (typeof(ELEMENT) === 'undefined') {
// 注意一定要用 document.write,因为它会阻塞后面的代码
document.write('<script src="./js/element-ui.js"><\/script>')
}
</script>
是否使用 CDN
CDN 引入的代码是没有经过 tree-shaking 优化的。
如果仅仅使用了第三方库的一部分功能,CDN 依然会全量引入所有内容,反而浪费。
例如 只是使用了 element-ui 的一两个组件,那经过 webpack tree-shaking 优化过的代码可能会更小。