打包优化:借助 CDN 加载核心库 vite-plugin-cdn2
概述
Vite 构建打包后,第三方依赖(Vue、Element Plus、ECharts 等)会被打包进最终产物,导致体积过大。通过 vite-plugin-cdn2 插件,可以将这些核心库替换为 CDN 加载,显著减小打包体积。
打包体积分析
为什么 ES6 import 还是大
Vite 构建不仅处理项目代码中的 import/export,还受以下因素影响:
| 因素 | 说明 |
|---|---|
| 第三方插件 | unplugin-vue-components、auto-import 等会自动引入依赖 |
| 构建配置 | external 配置决定哪些模块不打包 |
| 样式处理 | Element Plus 等组件库的样式也被打包 |
vite-plugin-cdn2 配置
安装
pnpm add -D vite-plugin-cdn2
bash
基础配置
// vite.config.ts
import { defineConfig } from 'vite'
import { cdn } from 'vite-plugin-cdn2'
export default defineConfig({
plugins: [
cdn({
modules: [
{
name: 'vue',
var: 'Vue',
path: 'https://unpkg.com/vue@3/dist/vue.global.prod.js'
},
{
name: 'vue-router',
var: 'VueRouter',
path: 'https://unpkg.com/vue-router@4/dist/vue-router.global.prod.js'
},
{
name: 'element-plus',
var: 'ElementPlus',
path: 'https://unpkg.com/element-plus/dist/index.full.min.js',
css: 'https://unpkg.com/element-plus/dist/index.css'
},
{
name: 'echarts',
var: 'echarts',
path: 'https://unpkg.com/echarts@5/dist/echarts.min.js'
}
],
// 仅在生产模式启用
prodUrl: (module, prodUrl) => prodUrl
})
]
})
typescript
CDN 配置项说明
| 字段 | 类型 | 说明 |
|---|---|---|
name | string | npm 包名 |
var | string | 全局变量名(CDN 暴露的全局变量) |
path | string | CDN JS 文件地址 |
css | string/string[] | CDN CSS 文件地址(可选) |
local | string | 本地开发时的替代路径(可选) |
分环境配置
// vite.config.ts
import { defineConfig } from 'vite'
import { cdn } from 'vite-plugin-cdn2'
const cdnModules = [
{
name: 'vue',
var: 'Vue',
path: 'https://unpkg.com/vue@3/dist/vue.global.prod.js'
},
{
name: 'element-plus',
var: 'ElementPlus',
path: 'https://unpkg.com/element-plus/dist/index.full.min.js',
css: 'https://unpkg.com/element-plus/dist/index.css'
}
]
export default defineConfig({
plugins: [
// 仅生产环境启用 CDN
process.env.NODE_ENV === 'production' && cdn({ modules: cdnModules })
].filter(Boolean)
})
typescript
CDN 源选择
| CDN 源 | 国内速度 | 稳定性 | 说明 |
|---|---|---|---|
| unpkg | 中 | 高 | npm 包默认 CDN |
| cdnjs | 快 | 高 | Cloudflare 提供 |
| jsdelivr | 快 | 高 | 支持 npm、GitHub |
| npmmirror (淘宝) | 最快 | 高 | 国内镜像 |
切换 CDN 源
// 使用 jsdelivr
{
name: 'vue',
var: 'Vue',
path: 'https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js'
}
// 使用淘宝镜像
{
name: 'vue',
var: 'Vue',
path: 'https://registry.npmmirror.com/vue/3/dist/vue.global.prod.js'
}
typescript
打包效果对比
| 指标 | CDN 前 | CDN 后 |
|---|---|---|
| index.js 体积 | ~800KB | ~200KB |
| 首屏加载 | 较慢 | 快(CDN 缓存) |
| 构建时间 | 较长 | 更短 |
| 离线可用 | 是 | 否(需网络) |
注意事项
| 注意点 | 说明 |
|---|---|
| 开发模式不启用 | CDN 仅用于生产环境,开发模式保留本地模块 |
| reserves 配置 | 确保 reserves 变量根据环境正确控制 |
| CSS 也走 CDN | Element Plus 的 CSS 也应通过 CDN 加载 |
| 版本锁定 | CDN URL 中指定具体版本号,避免兼容性问题 |
| 全局变量名 | var 必须与 CDN 文件暴露的全局变量名一致 |
实践要点
- CDN 外部化是将核心库从打包产物中移除,通过 CDN 链接加载
vite-plugin-cdn2通过替换 import 为全局变量引用实现- 仅在生产环境启用,开发环境保留本地模块以保持热更新
- CSS 文件也需配置 CDN,否则样式丢失
- 国内项目优先使用 jsdelivr 或淘宝镜像 CDN
↑