Skip to content
常见陷阱与最佳实践

常见陷阱与最佳实践

本章汇总 Vite 开发中最常见的陷阱和推荐的最佳实践,并附带上线前检查清单。


常见陷阱汇总

开发环境

# 陷阱 现象 解决方案
1 index.html 放在 public/ 开发服务器找不到入口 Vite 要求 index.html项目根目录
2 public 中的文件用 import 导入 报错找不到模块 public/ 中文件不能 import,只能用绝对路径引用
3 动态 import 的包未预构建 首次加载报 CommonJS 错误 将动态导入的包加到 optimizeDeps.include
4 环境变量没用 VITE_ 前缀 import.meta.env.MY_VARundefined 客户端变量必须以 VITE_ 开头(或配置 envPrefix
5 .env 变更后未重启 变量值不更新 修改 .env 文件后必须重启 Vite
6 CommonJS 依赖在浏览器报错 module is not defined 确保该包在预构建列表中,或使用 optimizeDeps.include
7 WSL2/Docker 下文件变更不触发 HMR 改了代码页面无反应 使用 usePolling: true (server.watch)
8 base 路径缺少末尾 / 资源 404 子路径部署时 base: '/my-app/' 必须有末尾斜杠
9 路径别名的 @ 在 CSS 中不生效 CSS url() 中的 @/... 解析失败 CSS 中需加 ~ 前缀:url('~@/assets/...') 或使用 @import
10 修改 vite.config.js 后 HMR 不生效 配置变更不反映到开发服务器 配置文件修改后需手动重启开发服务器
11 开发时使用 type: "module" 但 CJS 插件报错 插件加载失败 vite.config.js 可以使用 ESM(.mjs"type": "module"),Vite 会自动处理
12 define 中使用非 JSON 值 构建报语法错误 define 的值必须是已序列化的 JSON 字符串(如 JSON.stringify(val)
13 new URL() 使用纯变量路径 构建报错 路径必须包含静态部分,例如 new URL(./${name}.png, import.meta.url)

构建产物的坑

# 陷阱 现象 解决方案
14 build.target 设置过低导致大量 polyfill 产物体积异常大 按需设置 target,现代项目用 'modules' 即可
15 第三方库无 sideEffects 标记导致 Tree Shaking 失效 按需导入仍打包了全量 检查库的 package.json 中是否有 "sideEffects": false
16 CSS 中 @import 路径错误 构建时 CSS 404 使用相对路径或 @import '@/styles/...' 别名
17 页面作为 chunk 后 CSS 丢失 页面样式不显示 确保 CSS 在组件中被 import,已自动被 CSS Code Split
18 Sourcemap 在生产环境泄露源码 源码暴露 生产构建关闭 sourcemap 或使用 'hidden'
19 库模式未外部化依赖 打包进库的 node_modules 导致体积爆炸 设置 rollupOptions.external 排除框架依赖
20 路径别名在构建产物中未正确解析 dist 文件中路径错误 resolve.alias 而非硬编码相对路径
21 assetsInlineLimit 设置过大 JS 文件体积暴涨 合理设置阈值(默认 4KB 合适);CDN 场景可适当减小

框架特有的坑

# 陷阱 说明
22 React: .js 文件使用 JSX 语法 改为 .jsx 扩展名,或者配置 esbuild.jsx: 'transform'
23 React: HMR 不保留状态 确保组件是具名导出且使用 PascalCase
24 Vue: <script setup> 中 import 的组件未注册 unplugin-vue-components 配置缺失
25 CSS Modules: 类名被 - 分隔时 JS 访问方式错误 styles['my-class'] 而非 styles.my-class

最佳实践清单

项目配置

  • 使用 defineConfig 包裹配置获取 TS 类型提示
  • 根据 command / mode 条件加载插件
  • 设置 resolve.alias 路径别名并在 tsconfig.json 中同步
  • .env 文件分层:.env(默认)、.env.development.env.production
  • .env.local 加入 .gitignore
  • 敏感信息绝不VITE_ 前缀(或配置严格的 envPrefix

开发阶段

  • 启动时用 --open 自动打开浏览器
  • 代理 API 请求到后端 server.proxy
  • 动态 import 的包加入 optimizeDeps.include
  • 大型项目配置 server.warmup 预热关键文件
  • WSL2/Docker 用户配置 server.watch.usePolling

构建阶段

  • 选择合适的 build.target(现代项目用 moduleses2020
  • 配置合理的代码分割策略 manualChunks
  • 外部化库模式的依赖
  • 生产构建关闭 sourcemap(或 'hidden'
  • 使用 rollup-plugin-visualizer 分析构建产物
  • index.htmlscript / link 使用相对路径或正确的 base

部署阶段

  • 部署前运行 vite preview 本地验证构建产物
  • 非根路径部署设置 base
  • 配置 Nginx/CDN 强缓存静态资源(带 hash 的文件)
  • index.html 设为 no-cache
  • 启用 gzip / brotli 压缩

生产检查清单

上线前逐项确认:

□ 构建成功:npm run build 无报错
□ 本地预览:npm run preview 功能正常
□ 路由模式:SPA fallback 已配置(Nginx try_files / 服务器重定向)
□ API 代理:生产环境 API 地址正确(环境变量或 base URL)
□ 子路径:若部署在子路径,base 已设置且末尾含 /
□ 静态资源:所有资源正确加载(路径、CDN)
□ sourcemap:已关闭或设为 hidden(不暴露源码)
□ 环境变量:生产变量以 VITE_ 前缀正确配置
□ 缓存策略:HTML 不缓存,assets/ 强缓存
□ CSP(内容安全策略):若启用,Vite 开发时的 ESM 和 eval 不受影响
□ HTTPS:生产环境强制启用
□ 压缩:CDN / Nginx 中 gzip/brotli 已开启
□ 体积告警:chunk 体积在合理范围(单文件 < 500KB gzip)
□ 浏览器兼容:build.target 匹配目标用户群
□ 错误监控:Sentry 等工具已接入并配置 sourcemap 上传

Vite 专属调试技巧

查看预构建结果

# 检查预构建缓存
ls node_modules/.vite/

# 手动清除并重新预构建
rm -rf node_modules/.vite
vite --force

开发阶段查看模块图

// 安装 vite-plugin-inspect
npm i -D vite-plugin-inspect
import inspect from 'vite-plugin-inspect'

export default defineConfig({
  plugins: [inspect()],
})

访问 http://localhost:5173/__inspect/ 查看模块转换的中间状态。

HMR 调试

// 在浏览器控制台中查看 HMR 日志
if (import.meta.hot) {
  import.meta.hot.on('vite:beforeUpdate', (payload) => {
    console.log('HMR 即将更新:', payload)
  })
  import.meta.hot.on('vite:afterUpdate', (payload) => {
    console.log('HMR 已完成更新:', payload)
  })
  import.meta.hot.on('vite:error', (payload) => {
    console.error('HMR 错误:', payload)
  })
}

常见启动错误速查

错误信息 原因 解决
Cannot find module 'xxx' 依赖未安装或预构建失败 npm install + vite --force
@import 'xxx' CSS 404 CSS 中 @import 路径错误 使用项目根相对路径或别名
process is not defined 代码中使用了 Node.js API 改用 import.meta.env 或 polyfill
Buffer is not defined 浏览器无 Buffer npm i -D vite-plugin-node-polyfills
global is not defined 浏览器无 global define: { global: 'globalThis' }
Dynamic require of "xxx" is not supported CJS 的 require() 在 Vite 中不兼容 改用 ESM import

升级 Vite 版本

npm i -D vite@latest

重大版本变化

版本 关键变化
Vite 6 Node.js 18+(2024.12)
Vite 5 Node.js 18+,Rollup 4,清理废弃 API
Vite 4 Node.js 14.18+,Rollup 3,默认 ESM
Vite 3 新文档站,Svelte/Vue 模板更新
Vite 2 完全重写,插件生态系统建立

💡 最佳实践:升级前先阅读 Vite 发布说明 的 Breaking Changes 部分。


环境变量安全

❌ 错误做法 ✅ 正确做法
VITE_DB_PASSWORD 中存数据库密码 只暴露非敏感的公开配置(API 地址等)
.env 中存储密钥并提交到 Git 敏感信息用 .env.local(已 gitignore)
把所有环境变量前缀设为空字符串 只暴露必要的变量前缀
在客户端代码中硬编码 key 所有令牌都应通过后端 API 获取

🚨 安全警告:任何以 VITE_ 开头的环境变量都将打包进客户端 JS 文件,用户可以直接查看。永远不要在其中存放密钥、令牌、密码等敏感信息。