手动分包
手动分包,可以减少打包时间,减少打包体积,减少打包后的文件大小,提高打包速度。
以下是分包前 vite.config.js 的代码
javascript
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
此时打包后的文件大小为 3.5MB,即使在 grip 压缩后仍有 1 MB 左右。 打包耗时约 23 秒。
于是对 vite.config.js 进行优化,手动分包。
javascript
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
build:{
rollupOptions: {
output: {
manualChunks: {
// 只保留第三方库的分包
'vendor': ['vue', 'vue-router', 'pinia', 'ant-design-vue'],
'utils': ['axios', 'lodash']
}
}
},
chunkSizeWarningLimit: 1000,
},
})
此时打包后的文件大小为 1.99 MB,即使在 grip 压缩后仍有 0.529 MB 左右。 打包耗时约 16 秒。
自动导入插件 unplugin-vue-components
在手动分包的基础上,采用 unplugin-vue-components 插件,可以进一步减少打包体积,提高打包速度。
首先安装 unplugin-vue-components
bash
npm install unplugin-vue-components -D
因为 ant-design-vue 的样式文件默认是 less 格式的,因此还需额外配置样式处理器
javascript
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite';
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [
AntDesignVueResolver({
importStyle: 'less',
resolveIcons: true,
}),
],
}),
],
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
build:{
rollupOptions: {
output: {
manualChunks: {
// 只保留第三方库的分包
'vendor': ['vue', 'vue-router', 'pinia', 'ant-design-vue'],
'utils': ['axios', 'lodash']
}
}
},
chunkSizeWarningLimit: 1500,
},
})
使用了按需导入插件之后,那么就需要 main.js 中取消全局导入(最基本的样式还是要全局导入)
javascript
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { createPersistedState } from 'pinia-plugin-persistedstate';
import App from './App.vue';
import router from './router';
// 只对样式进行全局导入
import 'ant-design-vue/dist/reset.css';
const app = createApp(App);
const pinia = createPinia();
// 使用持久化插件
pinia.use(createPersistedState());
app.use(pinia);
app.use(router);
app.mount('#app');
此时对比刚开始的打包文件大小,原始文件总体积减少了 1.269 MB 左右。 此时原始文件约为1258.66 kB, 压缩体积为 390.17 kB
在此基础上,继续优化,使用公共 CDN 加速
使用了 字节 CDN,并配置多个 CDN 源备用
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>招投标平台</title>
<!-- CDN 错误处理 -->
<script>
window.CDN_FAILED = false;
function loadBackupCDN(lib) {
if (window.CDN_FAILED) return;
console.warn(`失败`);
window.CDN_FAILED = true;
}
</script>
<!-- 主要 CDN - 字节 -->
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/3.3.4/vue.global.prod.min.js"
onerror="loadBackupCDN('vue')"></script>
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue-router/4.2.4/vue-router.global.prod.min.js"
onerror="loadBackupCDN('vue-router')"></script>
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/pinia/2.1.6/pinia.iife.prod.min.js"
onerror="loadBackupCDN('pinia')"></script>
<!-- 备用 CDN - 七牛云 -->
<script defer src="https://cdn.staticfile.org/vue/3.3.4/vue.global.prod.min.js"></script>
<script defer src="https://cdn.staticfile.org/vue-router/4.2.4/vue-router.global.prod.min.js"></script>
<script defer src="https://cdn.staticfile.org/pinia/2.1.6/pinia.iife.prod.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
vite.config.js 配置
javascript
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite';
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [
AntDesignVueResolver({
importStyle: 'less',
resolveIcons: true,
}),
],
}),
],
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
build:{
rollupOptions: {
external: ['vue', 'vue-router', 'pinia', 'ant-design-vue'],
output: {
manualChunks: {
'utils': ['axios', 'lodash']
},
globals: {
vue: 'Vue',
'vue-router': 'VueRouter',
pinia: 'Pinia',
'ant-design-vue': 'antd'
}
}
},
chunkSizeWarningLimit: 1500,
},
})
👆
- 此时 Vue全家桶从 CDN 加载,
- UI 库和工具库还是从本地打包
- 有备用 CDN 源,可以防止 CDN 加载失败
- 优势: ✅ 利用 CDN 缓存加速 ✅ 减小服务器压力 ✅ 首次加载更快 ✅ 有备用方案,更可靠
- 风险控制: ✅ 多 CDN 源备份 ✅ 失败自动切换 ✅ 只把最稳定的库放 CDN ✅ 其他依赖还是本地打包
external配置:
- 优点: ✅ 完全不打包这些库,体积最小 ✅ 可以利用 CDN 缓存 ✅ 减少构建时间
- 缺点: ❌ 强依赖 CDN 的可用性 ❌ 需要手动管理 CDN 版本 ❌ 可能出现版本不匹配问题
manualChunks 配置
- 优点: ✅ 更可控,不依赖外部资源 ✅ 版本可控,确保一致性 ✅ 适合私有部署 ✅ 便于调试
- 缺点: ❌ 打包体积相对较大 ❌ 无法利用公共 CDN 缓存 ❌ 构建时间较长
此时打包后文件大小约为 1161.22kB,压缩后为 351.60kB