Vue3 + Vite 环境变量配置指南:从模式管理到类型提示
做过真实项目的同学都知道,环境变量是前端工程化的基础,用好它能让项目的安全性、灵活性和可维护性大幅提升。核心原因有三点:
安全性:敏感配置(如接口地址、密钥)无需硬编码到业务代码,避免代码泄露带来的风险
灵活性:开发、测试、生产等不同环境可配置不同参数,无需修改代码即可快速切换
可维护性:所有配置集中管理,无需在项目各个角落查找配置项,团队协作更高效
本文内容以概念和实战配置为主,代码量不多,看完就能直接落地到你的 vue3 项目中。
先搞懂:Vite 中的模式 Mode
聊环境变量前,必须先了解 Vite 的模式(mode)——它决定了项目的构建和运行环境,是环境变量加载的核心依据。
1. Vite 默认的两种模式
Vite 内置了两个基础模式,分别对应开发和生产场景,可通过 import.meta.env.MODE 直接获取当前模式:
// main.ts 中测试
const currentMode = import.meta.env.MODE
console.log('当前运行模式:', currentMode)执行 pnpm dev 启动开发服务,输出:development(开发模式)
执行 pnpm build 打包后通过 pnpm preview 预览,输出:production(生产模式)
2. 企业级项目需自定义模式
默认的两种模式远不能满足企业级需求,实际项目中通常还会有概念验证环境(poc)、集成测试环境(sit)、用户接受测试环境(uat)等,这时候就需要通过 --mode 参数自定义模式。
我们以 dev(开发)、uat(测试)、prod(生产)三套核心环境为例,修改 package.json 的 scripts 命令,扩展开发和打包脚本:
{
"scripts": {
"dev:dev": "vite --mode dev",
"dev:uat": "vite --mode uat",
"build:dev": "run-p type-check \"build-only {@} --mode dev\" --",
"build:uat": "run-p type-check \"build-only {@} --mode uat\" --",
"build:prod": "run-p type-check \"build-only {@} --mode prod\" --"
}
}💡 企业级小提示:本地开发几乎不允许直接连接生产环境,因此无需配置 dev:prod 命令,避免误操作。
Vite 环境变量核心规则
搞定模式后,正式进入环境变量配置。Vite 会自动加载项目根目录下的 .env 系列文件,且有一套严格的规则,遵循这些规则才能避免配置失效。
1. 核心基础规则
Vite 会根据当前 mode 自动设置 NODE_ENV,无需手动在 .env 文件中配置
自定义环境变量必须以 VITE_ 为前缀,否则不会被暴露到浏览器端(防止服务端环境变量泄露)
所有环境变量的原始值均为字符串类型,如需其他类型需手动转换
Vite 支持 .env 文件的多种变体,用于区分通用配置和环境专属配置
2. .env 文件的四种变体
Vite 支持 4 种 .env 文件格式,覆盖通用配置、环境专属配置、本地私有配置场景:
| 文件 | 说明 |
|---|---|
| .env | 所有环境的通用配置,项目所有成员共享 |
| .env.local | 所有环境的本地私有配置,仅当前开发者使用 |
| .env.[mode] | 指定模式的专属配置,如 .env.dev、.env.uat,项目成员共享 |
| .env.[mode].local | 指定模式的本地私有配置,如 .env.dev.local |
⚠️ 重要提醒:所有带 .local 的文件都是开发者私有配置,必须添加到 .gitignore 中(Vite 初始化的项目默认已忽略 *.local),避免提交到代码仓库。
3. 环境变量的加载优先级
如果同一个环境变量在多个文件中定义,Vite 会按「本地私有 > 环境专属 > 全局私有 > 全局通用」的规则加载,实测优先级从高到低为:.env.[mode].local > .env.[mode] > .env.local > .env。
我们用一个简单的测试验证:
新建 .env,定义 VITE_APP_NAME=demo_default,运行 pnpm dev:dev,页面显示 demo_default
新建 .env.local,定义 VITE_APP_NAME=demo_local,页面立即更新为 demo_local
新建 .env.dev,定义 VITE_APP_NAME=demo_dev,页面更新为 demo_dev
新建 .env.dev.local,定义 VITE_APP_NAME=demo_dev_local,页面最终显示 demo_dev_local
完善 TS 类型提示:告别无提示开发
使用 TypeScript 开发时,直接通过 import.meta.env 获取自定义环境变量,IDE 不会有任何代码提示,开发体验极差。我们只需在根目录的 env.d.ts 文件中扩展类型,即可实现完美的类型提示。
1. 基础类型声明
在 env.d.ts 中添加 ImportMetaEnv 和 ImportMeta 的接口扩展:
/// <reference types="vite/client" />
interface ImportMetaEnv {
// 自定义环境变量,按需添加
readonly VITE_APP_NAME: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}此时在代码中输入 import.meta.env.VITE_,IDE 就会自动提示已声明的环境变量。
2. 扩展多类型变量声明
如果配置了数字、布尔类型的环境变量(如端口、调试开关),需同步在接口中声明,保证类型一致性:
interface ImportMetaEnv {
readonly VITE_APP_NAME: string
readonly VITE_api_PORT: number // 数字类型
readonly VITE_DEBUG: boolean // 布尔类型
}封装 Env 工具类:简化环境变量读取
原生获取环境变量需要手动做类型转换,且代码冗余,我们可以封装一个静态工具类,统一处理环境变量的读取、类型转换和环境判断,让代码更优雅。
1. 创建工具类文件
在 src/utils/ 下新建 env.ts,实现核心方法:
export class Env {
/**
* 获取基础环境变量(默认字符串)
* @param key 环境变量名
* @param defaultValue 默认值
*/
static get<T>(key: keyof ImportMetaEnv, defaultValue?: T): T | string {
const value = import.meta.env[key]
return value ?? (defaultValue as T)
}
/** 获取数字类型环境变量,自动转换 */
static getNumber(key: keyof ImportMetaEnv, defaultValue?: number): number {
const value = import.meta.env[key]
if (value === undefined) return defaultValue as number
return Number(value)
}
/** 获取布尔类型环境变量,自动转换(true/1 为 true,其他为 false) */
static getBoolean(key: keyof ImportMetaEnv, defaultValue?: boolean): boolean {
const value = import.meta.env[key]
if (value === undefined) return defaultValue as boolean
return value === 'true' || value === '1'
}
/** 获取当前环境标识(dev/uat/prod) */
static get env(): 'dev' | 'uat' | 'prod' {
return this.get('VITE_ENV', 'dev') as 'dev' | 'uat' | 'prod'
}
/** 是否为开发环境 */
static get isDev(): boolean {
return this.env === 'dev'
}
/** 是否为测试环境 */
static get isUat(): boolean {
return this.env === 'uat'
}
/** 是否为生产环境 */
static get isProd(): boolean {
return this.env === 'prod'
}
}2. 工具类的使用与测试
在 main.ts 中引入并测试,无需手动转换类型,直接调用即可:
import { Env } from '@/utils/env'
console.log('项目名称:', Env.get('VITE_APP_NAME'))
console.log('接口端口:', Env.getNumber('VITE_API_PORT'))
console.log('是否开启调试:', Env.getBoolean('VITE_DEBUG'))
console.log('是否为开发环境:', Env.isDev)
console.log('是否为生产环境:', Env.isProd)控制台会正确输出对应类型的值,开发时直接通过 Env.xxx 调用,简洁又高效。
特殊场景:vite.config.ts 中获取环境变量
在 vite.config.ts 中,我们经常需要根据环境变量配置代理、插件、基础路径等,但不能直接使用 import.meta.env,原因有两点:
vite.config.ts 运行在 Node.js 环境(CommonJS 模块规范),而 import.meta.env 是 ES 模块的浏览器环境变量
vite.config.ts 在 Vite 启动早期阶段执行,此时 Vite 尚未加载和处理环境变量,import.meta.env 还未生成
正确方式:使用 loadEnv 函数
Vite 提供了 loadEnv 函数,可手动根据当前模式加载对应的 .env 文件,返回解析后的环境变量对象,使用方式如下:
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
// 接收 mode 参数,获取当前运行模式
export default defineConfig(({ mode }) => {
// 加载环境变量:参数1-当前模式,参数2-项目根目录,参数3-变量前缀(默认为 VITE_)
const env = loadEnv(mode, process.cwd(), 'VITE_')
console.log('Vite配置中获取的环境变量:', env)
return {
plugins: [vue()],
// 可根据环境变量配置自定义内容,如代理、基础路径
server: {
proxy: {
'/api': {
target: env.VITE_API_BASE_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}
})如果需要加载所有环境变量(包括非 VITE_ 前缀),只需将第三个参数设为空字符串 ''。
方案总结
本文为 Vue3 + Vite 企业级项目打造了一套可直接落地的环境变量管理方案,核心能力包括:
配置了 dev/uat/prod 三套核心环境,支持通过 --mode 快速切换
完善了 TS 类型声明,实现 IDE 代码自动提示,告别类型模糊
封装了 Env 工具类,统一处理环境变量的读取和类型转换,简化业务代码
实现了 vite.config.ts 中的环境变量加载,支持根据环境动态配置 Vite
这套方案轻量、优雅且符合企业级开发规范,集成到 Vue3 通用模板后,能大幅提升项目的工程化水平和开发效率。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!