Vite 环境变量暴露边界与构建替换
Vite 的环境变量要先按“谁能看到”来分,而不是按文件名判断是否安全。带有 VITE_ 前缀的变量会通过 import.meta.env 暴露给客户端代码;生产构建时,这些引用还会被静态替换进前端资源。它适合放公开 API 地址、功能开关或构建标识,不适合放 API 密钥、数据库密码和签名私钥。
官方地址:https://vite.dev/guide/env-and-mode
判断标准很简单:只要浏览器需要它,就假设用户、代理和抓包工具都能看到它。真正的秘密应留在服务端,由服务端代替浏览器访问受保护的资源。
先划分资产:哪些配置可以进浏览器
可以把配置分成三层。第一层是公开配置,例如前端请求的服务地址、应用显示名和非敏感功能开关;第二层是可观测标识,例如构建环境名、版本号或公开的追踪标识;第三层是服务端秘密,例如第三方服务密钥、数据库凭据和签名材料。前两层进入浏览器后仍要接受公开审视,第三层不能通过环境变量下发。

例如下面的文件可以表达“哪些值是公开的”,但注释里的秘密不能因为放在 .env 就变成私密:
# .env.production:只放可以公开给浏览器的构建配置
VITE_API_BASE=https://api.example.com
VITE_FEATURE_REPORT=true
# 不要这样写:构建后可能进入客户端资源
# VITE_PAYMENT_SECRET=replace-me
# 服务端秘密应由后端环境读取,不要加 VITE_ 前缀
PAYMENT_SECRET=server-only-value
这里的域名只是配置示例。实际项目应把服务端秘密交给后端或边缘函数,并让前端调用一个经过鉴权的业务接口。
识别暴露路径:前缀和 envPrefix 是入口
默认情况下,Vite 会把名称以 VITE_ 开头的变量挂到 import.meta.env 上;没有这个前缀的变量不会按这条默认规则暴露。项目可以用 envPrefix 自定义暴露前缀,因此安全审查不能只搜索 VITE_,还要查看 Vite 配置中的前缀设置。
// vite.config.js:只允许明确的公开前缀进入客户端代码
import { defineConfig } from 'vite'
export default defineConfig({
// 前缀越具体,误把服务端变量下发的机会越小
envPrefix: ['VITE_', 'PUBLIC_']
})
如果团队把前缀扩展为过于宽泛的值,保护边界就会变薄。命名本身不是权限控制,前缀只决定哪些值会被构建工具放进客户端;它不会替你判断字符串是不是密钥。
构建时发生什么:静态替换与模式文件
Vite 会加载通用文件和模式文件,例如 .env、.env.local、.env.production,并允许通过 --mode 选择构建模式。变量通常以字符串形式进入 import.meta.env,所以布尔值需要显式转换,不能把非空字符串直接当成布尔判断。

// config.ts:显式转换字符串,避免“false”被当成真值
const apiBase = import.meta.env.VITE_API_BASE
const reportEnabled = import.meta.env.VITE_FEATURE_REPORT === 'true'
// 生产构建选择对应模式文件,值会在构建阶段写入资源
console.log({ apiBase, reportEnabled })
“静态替换”意味着发布后再修改服务器上的 .env.production,通常不会改变已经生成的前端资源;要换值,需要重新构建,或者把这类配置改成由服务端接口在运行时返回。另一个细节是,动态拼接变量名不适合作为读取方式,构建工具需要看到明确的属性访问,才有稳定的替换边界。
按风险分级落地防护
低风险配置可以直接进入客户端,但仍应避免把内部网络拓扑、调试开关和不必要的路径暴露出去。中风险配置要限制作用域,例如只下发公开接口地址,并让后端继续执行权限判断。高风险秘密必须移出 Vite 客户端构建,改由后端保存和使用;前端拿到的只能是短期、最小权限的业务结果。
// server-route.js:服务端持有秘密,浏览器只调用业务接口
export async function createPayment(request) {
// 从服务端进程环境读取,不把密钥拼进前端响应
const secret = process.env.PAYMENT_SECRET
if (!secret) throw new Error('缺少服务端支付配置')
// 这里调用第三方服务并返回最小必要结果
return callProvider({ secret, orderId: request.orderId })
}
发布前可以形成一张简短清单:搜索所有自定义前缀;确认每个前缀变量都能公开;检查 envPrefix 是否过宽;区分构建期值和运行期值;在构建产物抽查变量名而不是把秘密交给前端。
常见问题
没有 VITE_ 前缀就一定安全吗?
不是。它只是不会按 Vite 默认前缀规则暴露,代码、插件、接口响应或其他打包配置仍可能泄露;最终要看数据是否进入客户端可见范围。
把密钥放到 .env.local 能避免泄露吗?
它有助于避免提交到版本库,但如果变量带有暴露前缀并被前端引用,构建后仍可能进入客户端资源。文件位置和客户端可见性是两件事。
想在发布后改 API 地址怎么办?
不要把它误当成已生成资源里的动态配置。可以重新构建,也可以让前端启动时读取受控的运行时配置接口;后者仍不能返回服务端秘密。
总结:先按可见性划分资产,再检查暴露前缀,最后确认模式文件和静态替换是否符合发布方式。Vite 能帮助你把公开配置注入前端,但不会替你完成秘密管理。
前端用 PerformanceObserver 采集核心指标的结构
- 上一篇
- 前端用 PerformanceObserver 采集核心指标的结构
- 下一篇
- ES module preload 减少首屏依赖等待的方法
-
- 文章 · 前端 | 1小时前 | 前端 · typescript ·
- TypeScript 自定义类型守卫收窄 API 响应
- 493浏览 收藏
-
- 文章 · 前端 | 1小时前 | 浏览器缓存 首屏加载 依赖图 JavaScript性能 ES module modulepreload
- ES module preload 减少首屏依赖等待的方法
- 254浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- 前端用 PerformanceObserver 采集核心指标的结构
- 298浏览 收藏
-
- 文章 · 前端 | 1小时前 | 前端 · css · 无障碍 :focus 焦点样式 :focus-visible 前端键盘焦点
- 前端键盘焦点样式与 :focus-visible 的应用
- 433浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- ARIA dialog 实现可访问弹窗的焦点管理
- 411浏览 收藏
-
- 文章 · 前端 | 1小时前 | css · 行高 CSS flex align-items inline-flex Baseline 文字图标对齐
- CSS Flex baseline 对齐文字和图标的做法
- 474浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- CSS Grid minmax 处理响应式列宽的方案
- 422浏览 收藏
-
- 文章 · 前端 | 1小时前 | 前端 · css · 卡片布局 换行 CSS text-wrap balance 多行标题 前端排版
- CSS text-wrap: balance 怎样改善多行标题换行
- 439浏览 收藏
-
- 文章 · 前端 | 1小时前 | 前端 · 性能优化 · javascript · ArrayBuffer postMessage 前端性能 结构化克隆 Web Worker transfer terminate
- Web Worker 分担大数据计算的消息设计
- 176浏览 收藏
-
- 文章 · 前端 | 1小时前 | 版本发布 · Service Worker Cache API 缓存版本 前端缓存 activate Service Worker更新
- Service Worker 缓存策略的版本更新方法
- 122浏览 收藏
-
- 文章 · 前端 | 1小时前 | 前端 · css · 可访问性 · 浏览器兼容 · prefers-reduced-motion animation-timeline 前端兼容 CSS scroll-timeline 滚动驱动动画
- CSS scroll-timeline 结合 prefers-reduced-motion 的降级处理
- 308浏览 收藏
-
- 文章 · 前端 | 2小时前 | html · javascript · 表单 · 浏览器API · 自定义按钮 前端表单 HTMLInputElement.showPicker input选择器
- HTMLInputElement.showPicker 怎样用自定义按钮打开选择器
- 106浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 500次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 558次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 587次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 539次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 349次使用
-
- golang 在windows中设置环境变量的操作
- 2022-12-29 484浏览
-
- Golang常用环境变量说明与设置详解
- 2023-01-07 428浏览
-
- Go testing.T.Setenv 为什么不能和并行测试混用:环境变量隔离与清理顺序
- 2026-08-27 429浏览
-
- Go Cmd.Environ 如何确认子进程环境:变量继承、PATH 解析与可复现启动
- 2026-08-28 250浏览
-
- Go testing.T.Setenv 怎么为测试设置可恢复的环境变量
- 2026-09-07 184浏览
