Vite 实战教程:alias/env/proxy 配置 + 打包优化避坑|Vue 工程化必备

【Vite】前端工程化实操:从路径别名到打包优化,彻底搞懂Vite核心配置,避开高频踩坑!

同学们好,我是 Eugene(尤金),一个拥有多年中后台开发经验的前端工程师~

(Eugene 发音很简单,/juːˈdʒiːn/,大家怎么顺口怎么叫就好)

你是否也有过:明明学过很多技术,一到关键时候却讲不出来、甚至写不出来?

你是否也曾怀疑自己,是不是太笨了,明明感觉会,却总差一口气?

就算想沉下心从头梳理,可工作那么忙,回家还要陪伴家人。

一天只有24小时,时间永远不够用,常常感到力不从心。

技术行业,本就是逆水行舟,不进则退。

如果你也有同样的困扰,别慌。

从现在开始,跟着我一起心态归零 ,利用碎片时间,来一次彻彻底底的基础扫盲

这一次,我们一起慢慢来,扎扎实实变强。

不搞花里胡哨的理论堆砌,只分享看得懂、用得上的前端干货,

咱们一起稳步积累,真正摆脱「面向搜索引擎写代码」的尴尬。

📑 文章目录

  • [一、alias:让 import 更清晰](#一、alias:让 import 更清晰 "#part1")
    • [1.1 为什么需要 alias?](#1.1 为什么需要 alias? "#part1-1")
    • [1.2 怎么配置?](#1.2 怎么配置? "#part1-2")
    • [1.3 常见踩坑](#1.3 常见踩坑 "#part1-3")
  • 二、env:环境变量怎么用
    • [2.1 为什么需要 env?](#2.1 为什么需要 env? "#part2-1")
    • [2.2 基本规则](#2.2 基本规则 "#part2-2")
    • [2.3 典型文件结构](#2.3 典型文件结构 "#part2-3")
    • [2.4 示例配置](#2.4 示例配置 "#part2-4")
    • [2.5 在代码里怎么用](#2.5 在代码里怎么用 "#part2-5")
    • [2.6 常见踩坑](#2.6 常见踩坑 "#part2-6")
  • 三、proxy:解决开发环境跨域
    • [3.1 为什么需要 proxy?](#3.1 为什么需要 proxy? "#part3-1")
    • [3.2 基本配置](#3.2 基本配置 "#part3-2")
    • [3.3 更完整的配置示例](#3.3 更完整的配置示例 "#part3-3")
    • [3.4 和 env 配合](#3.4 和 env 配合 "#part3-4")
    • [3.5 常见踩坑](#3.5 常见踩坑 "#part3-5")
  • 四、打包优化
    • [4.1 为什么需要打包优化?](#4.1 为什么需要打包优化? "#part4-1")
    • [4.2 代码分割(手动分包)](#4.2 代码分割(手动分包) "#part4-2")
    • [4.3 分包策略示例(按路由/模块)](#4.3 分包策略示例(按路由/模块) "#part4-3")
    • [4.4 CDN 外链(可选)](#4.4 CDN 外链(可选) "#part4-4")
    • [4.5 压缩与产物清理](#4.5 压缩与产物清理 "#part4-5")
    • [4.6 常见踩坑](#4.6 常见踩坑 "#part4-6")
  • 五、完整配置示例
  • 六、小结

一、alias:让 import 更清晰

1.1 为什么需要 alias?

没有 alias 时,你会经常看到这样的写法:

js 复制代码
import Button from '../../../components/Button.vue'
import { getUserInfo } from '../../../../api/user'

问题主要有两点:

  1. ../ 太多,路径难维护,容易写错

  2. 重构时移动文件,相对路径要全改一遍

用 alias 把常用目录映射成简短路径后,可以改成:

js 复制代码
import Button from '@/components/Button.vue'
import { getUserInfo } from '@/api/user'

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

1.2 怎么配置?

vite.config.js(或 vite.config.ts)里配置:

js 复制代码
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      // 方式一:映射到 src 目录
      '@': fileURLToPath(new URL('./src', import.meta.url)),
      // 方式二:可以配多个
      '@components': fileURLToPath(new URL('./src/components', import.meta.url)),
      '@api': fileURLToPath(new URL('./src/api', import.meta.url)),
    },
  },
})

要点:

  • fileURLToPath + new URL():在 Node 的 ESM 环境下拿到正确的绝对路径

  • import.meta.url:当前配置文件所在目录

  • ./src:相对于配置文件所在目录的路径

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

1.3 常见踩坑

坑 1:忘记在 IDE 里配置路径提示

Vite 能正确解析,但 IDE 可能不认识 @,需要加 jsconfig.jsontsconfig.json

json 复制代码
// jsconfig.json(用 JS 的项目)
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@components/*": ["src/components/*"],
      "@api/*": ["src/api/*"]
    }
  },
  "include": ["src/**/*"]
}
json 复制代码
// tsconfig.json(用 TS 的项目)
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@components/*": ["src/components/*"]
    }
  }
}

坑 2:alias 和 Vite 配置不一致

jsconfig/tsconfigpaths 要跟 vite.configalias 保持一致,否则可能出现:开发时没问题,打包后路径错误或 IDE 报错。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

二、env:环境变量怎么用

2.1 为什么需要 env?

不同环境需要不同配置,例如:

  • 开发环境:本地 API 地址、调试开关

  • 生产环境:线上 API 地址、关闭调试

如果写死在代码里,每次发版都要手动改,容易出错。用 env 可以按环境自动切换。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

2.2 基本规则

Vite 的环境变量规则:

  • 文件名必须是 .env.env.local.env.[mode].env.[mode].local 这类

  • 只有以 VITE_ 开头的变量会暴露给客户端

  • mode 默认是 development(dev)和 production(build)

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

2.3 典型文件结构

Plain 复制代码
项目根目录/
├── .env                 # 所有环境都加载
├── .env.local           # 本地覆盖,一般加在 .gitignore
├── .env.development     # 开发环境
├── .env.production      # 生产环境
└── .env.staging         # 可选:预发环境

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

2.4 示例配置

.env (公共变量)

Plain 复制代码
# API 基础路径(会被 .env.development / .env.production 覆盖)
VITE_APP_TITLE=我的项目

.env.development (开发)

Plain 复制代码
VITE_API_BASE_URL=http://localhost:3000/api
VITE_USE_MOCK=true

.env.production (生产)

Plain 复制代码
VITE_API_BASE_URL=https://api.yoursite.com
VITE_USE_MOCK=false

.env.local (本地覆盖,不提交)

Plain 复制代码
# 比如你本机端口不同
VITE_API_BASE_URL=http://localhost:8080/api

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

2.5 在代码里怎么用

js 复制代码
// 直接通过 import.meta.env 访问
console.log(import.meta.env.VITE_API_BASE_URL)
console.log(import.meta.env.VITE_USE_MOCK)
console.log(import.meta.env.MODE)  // 'development' | 'production'

如果要集中管理,可以再包一层:

js 复制代码
// src/config/env.js
export const config = {
  apiBaseUrl: import.meta.env.VITE_API_BASE_URL,
  useMock: import.meta.env.VITE_USE_MOCK === 'true',
  isDev: import.meta.env.DEV,
  isProd: import.meta.env.PROD,
}

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

2.6 常见踩坑

坑 1:没用 VITE_ 前缀

Plain 复制代码
API_URL=xxx   # ❌ 客户端拿不到
VITE_API_URL=xxx  # ✅ 正确

坑 2:把 env 当布尔用

js 复制代码
// env 读出来都是字符串
if (import.meta.env.VITE_USE_MOCK) { }  // 'true' 和 'false' 都是 truthy!
// 正确写法
if (import.meta.env.VITE_USE_MOCK === 'true') { }

坑 3:.env.local 被提交

.env.local 里常放本地密钥、端口等,要加到 .gitignore,不要提交。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

三、proxy:解决开发环境跨域

3.1 为什么需要 proxy?

前端开发时往往是 localhost:5173,接口在 api.yoursite.com,浏览器会因同源策略限制产生跨域。

后端配 CORS 是一种方式,但有时后端不方便改,或者你想在本地连不同环境的接口,这时用 Vite 的 proxy 最方便:浏览器只请求同源的 dev 服务器,由 dev 服务器转发到真实接口。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

3.2 基本配置

js 复制代码
// vite.config.js
export default defineConfig({
  server: {
    port: 5173,
    proxy: {
      // 简单写法:/api 开头的请求转发到目标服务器
      '/api': {
        target: 'https://api.yoursite.com',
        changeOrigin: true,
      },
    },
  },
})

这样访问 http://localhost:5173/api/user/info 时,会被转发到 https://api.yoursite.com/api/user/info

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

3.3 更完整的配置示例

js 复制代码
// vite.config.js
export default defineConfig({
  server: {
    port: 5173,
    open: true,
    proxy: {
      '/api': {
        target: 'https://api.yoursite.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''), // 转发时去掉 /api 前缀
        secure: false,
        configure: (proxy, options) => {
          proxy.on('proxyReq', (proxyReq, req, res) => {
            // 可选:加 token 等请求头
            // proxyReq.setHeader('Authorization', 'Bearer xxx')
          })
          proxy.on('proxyRes', (proxyRes, req, res) => {
            // 可选:处理响应
          })
        },
      },
      // 多个接口可以配多个代理
      '/upload': {
        target: 'https://upload.yoursite.com',
        changeOrigin: true,
      },
    },
  },
})

常用选项说明:

选项 作用
target 真实后端地址
changeOrigin 改请求头 Host,避免目标服务器校验失败
rewrite 重写请求路径,例如去掉 /api 前缀
secure 目标为 https 且证书有问题时,可设 false
[⬆ 返回目录](#选项 作用 target 真实后端地址 changeOrigin 改请求头 Host,避免目标服务器校验失败 rewrite 重写请求路径,例如去掉 /api 前缀 secure 目标为 https 且证书有问题时,可设 false ⬆ 返回目录 "#catalogue")

3.4 和 env 配合

开发环境用 proxy,生产用完整 URL,可以这样配合 env:

.env.development

Plain 复制代码
VITE_API_BASE_URL=/api

.env.production

Plain 复制代码
VITE_API_BASE_URL=https://api.yoursite.com

src/api/request.js

js 复制代码
const baseURL = import.meta.env.VITE_API_BASE_URL

export function request(url, options = {}) {
  return fetch(`${baseURL}${url}`, options)
}

开发时请求 /api/xxx,会被 proxy 转发;生产时直接请求完整域名。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

3.5 常见踩坑

坑 1:忘记 changeOrigin

目标为域名时,建议设 changeOrigin: true,否则可能被后端拒绝。

坑 2:rewrite 把路径改错了

要清楚 rewrite 前后路径的对应关系,比如:

js 复制代码
// 前端请求:/api/user/info
// 未 rewrite:https://api.xxx.com/api/user/info
// rewrite 去掉 /api:https://api.xxx.com/user/info
rewrite: (path) => path.replace(/^\/api/, ''),

要看后端实际路径再决定是否 rewrite。

坑 3:proxy 只在开发环境生效

server.proxy 只在 vite 开发服务器下生效,生产构建不会用到,生产环境依赖你配置的 VITE_API_BASE_URL 等。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

四、打包优化

4.1 为什么需要打包优化?

不做优化时常见问题:

  • 单个 JS 过大,首屏加载慢

  • 第三方库和业务代码混在一起,缓存利用差

  • 未压缩的包体积大

Vite 默认已经做了不少优化,我们再针对常见场景补充一些配置。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

4.2 代码分割(手动分包)

js 复制代码
// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          // Vue 全家桶单独打包
          'vue-vendor': ['vue', 'vue-router', 'pinia'],
          // 体积较大的 UI 库单独打包
          'element-plus': ['element-plus'],
        },
      },
    },
  },
})

这样可以把 Vue、路由、状态管理和 UI 库拆成独立 chunk,利于缓存。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

4.3 分包策略示例(按路由/模块)

js 复制代码
// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            // node_modules 里的包
            if (id.includes('vue') || id.includes('pinia') || id.includes('vue-router')) {
              return 'vue-vendor'
            }
            if (id.includes('element-plus')) {
              return 'element-plus'
            }
            return 'vendor'
          }
        },
        chunkFileNames: 'js/[name]-[hash].js',
        entryFileNames: 'js/[name]-[hash].js',
        assetFileNames: '[ext]/[name]-[hash].[ext]',
      },
    },
    chunkSizeWarningLimit: 1000, // 单 chunk 超过 1000kb 时警告
  },
})

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

4.4 CDN 外链(可选)

把 Vue、Element Plus 等用 CDN 引入,减小打包体积:

js 复制代码
// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      external: ['vue', 'vue-router', 'pinia', 'element-plus'],
      output: {
        globals: {
          vue: 'Vue',
          'vue-router': 'VueRouter',
          pinia: 'Pinia',
          'element-plus': 'ElementPlus',
        },
      },
    },
  },
})

index.html 中用 <script> 引入对应 CDN,并确保全局变量名和 globals 一致。

注意:一般 SPA 不推荐全部 external,可以只 external 少数大库,其余照常打包。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

4.5 压缩与产物清理

js 复制代码
// vite.config.js
export default defineConfig({
  build: {
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,  // 生产环境去掉 console
        drop_debugger: true,
      },
    },
    cssCodeSplit: true,
    sourcemap: false,
  },
})

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

4.6 常见踩坑

坑 1:manualChunks 拆得太碎

拆出太多小 chunk 会多很多请求,反而影响性能,一般把体积大的依赖拆几块即可。

坑 2:忘记配 chunkSizeWarningLimit

默认 500kb 会报警,可按项目实际情况调大,例如 1000 或 1500。

坑 3:生产 sourcemap

生产环境建议关掉 sourcemap,否则包体积会明显增大。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

五、完整配置示例

下面是一份整合了 alias、env、proxy 和打包优化的 vite.config.js 示例:

js 复制代码
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'

export default defineConfig({
  plugins: [vue()],

  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },

  server: {
    port: 5173,
    open: true,
    proxy: {
      '/api': {
        target: 'https://api.yoursite.com',
        changeOrigin: true,
      },
    },
  },

  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vue-vendor': ['vue', 'vue-router', 'pinia'],
        },
        chunkFileNames: 'js/[name]-[hash].js',
        assetFileNames: '[ext]/[name]-[hash].[ext]',
      },
    },
    chunkSizeWarningLimit: 1000,
    sourcemap: false,
  },
})

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

六、小结

配置项 作用 重点
alias 简化 import 路径 和 jsconfig/tsconfig 保持一致
env 按环境切换配置 必须 VITE_ 前缀,注意值是字符串
proxy 开发环境解决跨域 changeOrigin,和 env 配合使用
打包优化 减小体积、提升加载 合理分包,控制 chunk 数量和大小

建议在实际项目里按需启用和调整这些配置,有问题可以在评论区补充你的项目结构和错误信息,便于一起排查。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")


学习本就是一场持久战,不需要急着一口吃成胖子。哪怕今天你只记住了一点点,这都是实打实的进步。

后续我还会继续用这种大白话、讲实战的方式,带大家扫盲更多前端基础。

关注我,不迷路,咱们把那些曾经模糊的知识点,一个个彻底搞清楚。

如果你觉得这篇内容对你有帮助,不妨点赞+收藏,下次写代码卡壳时,拿出来翻一翻,比搜引擎更靠谱。

我是 Eugene,你的电子学友,我们下一篇干货见~

相关推荐
兆子龙1 小时前
一文彻底搞懂 OpenClaw 的架构设计与运行原理(万字长文)
javascript
leafyyuki1 小时前
用 AI 和 SDD 重构 Vue2 到 Vue3 的实践记录
前端·人工智能
boooooooom2 小时前
别再用错 ref/reactive!90%程序员踩过的响应式坑,一文根治
javascript·vue.js·面试
德育处主任2 小时前
『NAS』一句话生成网页,在NAS部署UPage
前端·javascript·aigc
前端老兵AI2 小时前
前端工程化实战:Vite + ESLint + Prettier + Husky 从零配置(2026最新版)
前端·vite
bluceli2 小时前
浏览器渲染原理与性能优化实战指南
前端·性能优化
张元清2 小时前
Astro 6.0:被 Cloudflare 收购两个月后,这个"静态框架"要重新定义全栈了
前端·javascript·面试
凉拌西红柿2 小时前
如何用工具定位性能瓶颈
前端
青青家的小灰灰2 小时前
深入理解 async/await:现代异步编程的终极解决方案
前端·javascript·面试