📖 第一部分:理解 Vite 打包的核心 (vite.config.js)
你的所有打包配置,都集中在项目根目录下的 vite.config.js (或 .ts) 文件里。它就像是你给 Vite 下达的“打包说明书”。
一个最基础的 vite.config.js 文件长这样:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
})我们所有的精细化配置,都将在这个 defineConfig 对象里展开。
🚀 第二部分:基础但必须的配置
1. 设置项目根目录和公共基础路径 (base)
- 是什么:
base决定了你项目中所有资源(JS, CSS, 图片)URL 的前缀。 - 为什么需要:
- 默认情况:
base: '/'。打包后,index.html引用 JS 的路径是<script src="/assets/index.js">。这适用于部署在域名根目录(如https://example.com/)的项目。 - 部署在子目录:如果你的项目要部署在
https://example.com/my-app/,你就必须设置base: '/my-app/'。否则,浏览器会去根目录找资源,导致 404,页面白屏。
- 如何配置:
// vite.config.js
export default defineConfig({
base: '/my-app/', // <-- 根据你的部署路径修改
plugins: [vue()],
})2. 配置开发服务器 (server)
这是你运行 npm run dev 时 Vite 的行为,虽然不直接影响打包,但对开发体验至关重要。
host: 允许哪个 IP 访问你的开发服务器。设置为true或'0.0.0.0'可以让同局域网的手机或同事访问你的电脑 IP 来预览页面。port: 设置开发服务器的端口号,避免端口冲突。open: 运行dev命令时自动在浏览器打开页面。proxy: 开发环境下的跨域解决方案。这是dev模式下 Nginx 反向代理的替代品。- 如何配置:
// vite.config.js
export default defineConfig({
// ...
server: {
host: '0.0.0.0', // 允许 IP 访问
port: 8080, // 自定义端口
open: true, // 自动打开浏览器
proxy: {
// 键名是代理的标识,/api 是约定的前缀
'/api': {
target: 'http://api.backend.com', // 目标后端服务地址
changeOrigin: true, // 必须开启,修改请求头的 host
rewrite: (path) => path.replace(/^\/api/, ''), // 重写路径,去掉 /api
},
}
}
})解释 proxy: 当你在代码中请求 /api/users 时,Vite 会自动把它转发到 http://api.backend.com/users。注意:这只在开发环境生效!生产环境还是得靠 Nginx。
📦 第三部分:生产环境打包 (build) 精细化配置
这是你运行 npm run build 时的核心配置,直接决定了最终产物的质量。
1. 配置输出目录 (outDir) 和资源目录 (assetsDir)
- 是什么:
-
outDir: 打包后文件的输出目录,默认是dist。 -
assetsDir: 静态资源(JS, CSS, 图片等)在outDir中的存放目录,默认是assets。
- 为什么需要:方便管理或对接一些有特定目录结构要求的 CI/CD 流程。
- 如何配置:
// vite.config.js
export default defineConfig({
// ...
build: {
outDir: 'build', // 输出目录名
assetsDir: 'static' // 静态资源目录名
}
})-
打包后,文件会生成在
build/目录下,JS/CSS 在build/static/里。
2. 代码分割与摇树优化 (Chunking & Tree-shaking)
Vite 默认已经做得很好,但我们可以进一步优化。
-
rollupOptions.output.manualChunks: 手动代码分割。这是最重要的优化手段之一。 - 为什么需要:默认情况下,Vite 会把所有第三方库(如
vue,vue-router,axios,element-plus)都打包进一个巨大的vendor.js文件里。如果这个文件太大(比如超过 1MB),会严重影响首屏加载速度。通过手动分割,我们可以把这些库拆分成更小的块,利用浏览器的 HTTP/2 并行加载优势。 - 如何配置:
// vite.config.js
export default defineConfig({
// ...
build: {
rollupOptions: {
output: {
// manualChunks 配置
manualChunks(id) {
// 将 node_modules 中的模块单独打包
if (id.includes('node_modules')) {
// 获取模块的名称
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
}
}
}
}
})- 精细化配置
manualChunks:
// vite.config.js
import { splitVendorChunkPlugin } from 'vite'; // Vite 官方插件
export default defineConfig({
plugins: [vue(), splitVendorChunkPlugin()], // 使用插件简化配置
build: {
rollupOptions: {
output: {
manualChunks: {
// 将 Vue 相关库打包成一个 chunk
'vue-family': ['vue', 'vue-router', 'pinia'],
// 将 Element Plus 打包成一个 chunk
'element-plus': ['element-plus'],
// 将 ECharts 打包成一个 chunk
'echarts': ['echarts'],
}
}
}
}
})- 效果:打包后你会看到
vendor.js,vue-family.js,element-plus.js等多个文件,而不是一个臃肿的vendor.js。
3. 移除 console.log 和 debugger
- 为什么需要:生产环境代码中不应该包含调试信息。
- 如何配置:
// vite.config.js
export default defineConfig({
// ...
build: {
minify: 'terser', // Vite 默认使用 esbuild,但 terser 有更丰富的选项
terserOptions: {
compress: {
drop_console: true, // 移除 console
drop_debugger: true, // 移除 debugger
},
},
}
})4. 静态资源处理
-
assetsInlineLimit: 小于此阈值的图片或资源将被转为 base64 格式,内联到代码中。 - 为什么需要:减少小的 HTTP 请求数。但如果图片太大,转成 base64 会让 JS/CSS 文件体积剧增,得不偿失。
- 如何配置:
// vite.config.js
export default defineConfig({
// ...
build: {
assetsInlineLimit: 4096, // 4kb,小于 4kb 的将被转为 base64
}
})5. Sourcemap
-
sourcemap: 是否生成 sourcemap 文件。 - 为什么需要:Sourcemap 能让你在浏览器开发者工具中直接调试源码,而不是压缩后的代码。生产环境强烈建议关闭或设置为
hidden,以防源码泄露。 - 如何配置:
// vite.config.js
export default defineConfig({
// ...
build: {
sourcemap: false, // 生产环境关闭
}
})🧩 第四部分:完整的高级配置示例 (vite.config.js)
这是一个集成了上述所有优化点的、可以直接用于生产项目的配置模板。
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path' // 需要安装 @types/node
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
// 根据当前工作目录中的 `mode` 加载 .env 文件
const env = loadEnv(mode, process.cwd())
return {
// 1. 公共路径配置
// 如果部署在根目录,就是 '/';如果部署在子目录,就是 '/your-sub-path/'
base: env.VITE_APP_BASE || '/',
// 2. 插件
plugins: [
vue(),
],
// 3. 路径别名配置
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
// 4. 开发服务器配置
server: {
host: '0.0.0.0',
port: 8080,
open: true,
proxy: {
'/api': {
target: env.VITE_API_TARGET, // 从 .env 文件读取后端地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
// 5. 生产环境打包配置
build: {
outDir: 'dist',
assetsDir: 'assets',
sourcemap: false,
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
rollupOptions: {
output: {
// 优化打包,分包策略
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('element-plus')) {
return 'element-plus';
}
if (id.includes('echarts')) {
return 'echarts';
}
// 其他所有 node_modules 的依赖都打包进 vendor
return 'vendor';
}
},
// 对不同类型文件进行分类打包
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
},
},
},
}
})如何使用这个模板?
- 安装依赖:
npm install -D @types/node - 创建
.env文件:在项目根目录创建.env.development和.env.production文件来管理环境变量。
# .env.production
VITE_APP_BASE=/my-app/
VITE_API_TARGET=http://prod.api.com# .env.development
VITE_APP_BASE=/
VITE_API_TARGET=http://dev.api.com- 修改
package.json:
"scripts": {
"dev": "vite --mode development",
"build": "vite build --mode production",
"preview": "vite preview"
},这样,你就有了一套非常专业、可扩展的 Vite 打包配置了!
















