news 2026/10/7 20:24:28

Next.js 环境变量公开化:用 NEXT_PUBLIC_ 前缀把变量安全暴露给浏览器端代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Next.js 环境变量公开化:用 NEXT_PUBLIC_ 前缀把变量安全暴露给浏览器端代码
  • 文档
  • 教程
  • 知识库

【免费下载链接】til

:memo: Today I Learned

项目地址:https://gitcode.com/gh_mirrors/ti/til
点击查看免费下载

导读

在 Next.js 应用中,.env.development、.env.production等环境变量文件为不同环境(开发、测试、生产)提供了无缝切换配置的能力,但默认情况下这些变量不会进入浏览器端的客户端代码。本文基于 til 仓库的实战笔记,讲解为什么process.env.API_BASE_URL在客户端组件中会得到undefined,以及如何通过NEXT_PUBLIC_前缀把非敏感变量(如 API 基础地址)公开暴露给前端;同时结合仓库中的相关笔记,补充.env*文件的加载顺序、变量优先级与真实迁移场景,让你彻底掌握 Next.js 环境变量的公开化机制。

从.env文件说起:按环境切分配置

在 Next.js 项目中,环境变量的常见做法是把它写在 dotenv 格式的文件里,并按运行环境拆分。你可以在.env.development和.env.production中分别定义变量,从而让同一份代码在不同环境下读取到不同的值。

一个典型场景就是 API 请求的基础地址(base URL):开发环境指向本地服务器,生产环境指向线上服务器。可以这样定义:

API_BASE_URL=localhost:3000/api/v1

例如在.env.development中写入上述内容,开发环境的服务就能读到它;同理,在.env.production中写入线上地址,生产构建就使用线上地址。这是 dotenv 文件作为“环境级配置载体”的核心价值。

注意:上例中的localhost:3000/api/v1只是笔记中的示意写法,实际使用时应包含协议,例如http://localhost:3000/api/v1或https://api.example.com/api/v1,否则请求方无法正确解析。

客户端代码读不到环境变量:默认被排除在构建之外

把变量写进.env.development/.env.production后,问题很快就会出现:从任何客户端页面或组件里都取不到这个值。

process.env.API_BASE_URL //=> undefined

这是 Next.js 有意为之的安全设计。环境变量里存放的往往是私钥(private keys)、密钥(secrets)等敏感信息,如果默认就把所有环境变量打进公开的客户端代码(client code)包,等于把密钥直接暴露给任何能查看页面源码的人。因此:

  • 服务端(Server Components、API Routes、getServerSideProps等)可以读取全部环境变量;
  • 客户端(浏览器端执行的组件与页面代码)默认读不到任何环境变量;
  • Next.js在构建时默认将所有环境变量排除出客户端 bundle。

换句话说,不是变量没定义,而是 Next.js 出于安全考虑,刻意不让它进入浏览器可见的作用域。

用 NEXT_PUBLIC_ 前缀公开变量

如果某个变量的值并非机密(比如 API 基础地址),你希望它出现在浏览器端代码里,办法就是给变量名加上NEXT_PUBLIC_前缀:

NEXT_PUBLIC_API_BASE_URL=localhost:3000/api/v1

加上前缀之后,这个变量在任何客户端和服务端代码中都可以访问:

process.env.NEXT_PUBLIC_API_BASE_URL //=> 'localhost:3000/api/v1'

这背后的机制是:Next.js 在构建时会对代码中出现的process.env.NEXT_PUBLIC_*进行静态替换(inline)——它不是在运行时去读系统环境,而是在编译阶段就把字面量直接写入产出的 JavaScript 文件里。这也带来两个重要推论:

  1. 公开变量在构建时固化:NEXT_PUBLIC_变量的值取自构建(build)那一刻的环境,而不是运行时环境。如果你改了.env.production中的值,需要重新构建部署才能让线上生效。
  2. 只适用于非敏感信息:任何加了NEXT_PUBLIC_的变量都会以明文形式出现在浏览器可下载的 bundle 中,绝对不要用它存放 API 密钥、数据库密码、签名密钥等机密。

命名约定一览

变量类别示例客户端可读用途
普通环境变量API_BASE_URL否(返回undefined)服务端密钥、内部配置
公开环境变量NEXT_PUBLIC_API_BASE_URL是需要进入浏览器 bundle 的非敏感值

结合仓库笔记:.env 文件如何被加载与覆盖

要让NEXT_PUBLIC_变量真正“按环境生效”,还需要理解 Next.js 加载.env*文件的顺序。仓库中的另一篇笔记 precedence-of-dot-env-files.md 给出了完整的规则:

一个活跃开发中的项目里,.env*文件往往会有很多变体:

$ ls -a -1 .env* .env .env.development .env.development.local .env.development.local.example .env.local .env.production .env.test

Next.js 的加载逻辑是:

  • 始终尝试加载.env与.env.local(test环境除外,测试中不加载.env.local);
  • 根据NODE_ENV(取值development、test、production)再加载对应的环境专用文件,例如开发环境会加载.env.development与.env.development.local;
  • 像.env.development.local.example这类文件并不在加载清单里,它只是 dotenv 模板文件的社区约定命名(提供一份可复制的示例模板)。

变量覆盖优先级从高到低为:系统环境(即已经存在于process.env中的变量)最高,其次是按下列顺序查找文件,找到即用、不再继续:

  1. .env.$(NODE_ENV).local
  2. .env.local
  3. .env.$(NODE_ENV)
  4. .env

把这些规则与本文主题结合,可以得出一个实战要点:如果你希望开发环境使用http://localhost:3000/api/v1、生产环境使用线上地址,可以在.env.development和.env.production中分别定义NEXT_PUBLIC_API_BASE_URL;而.env.local中定义的公开变量会覆盖同名变量,适合本地临时调试。

仓库中的真实场景:全局批量迁移 NEXT_PUBLIC_ 变量

仓库里还有一篇与NEXT_PUBLIC_直接相关的实战笔记 negative-look-ahead-search-with-ripgrep.md,记录了一次真实的重构过程:在一个大型 monorepo 中,需要把大量NEXT_PUBLIC_SANITY_DATASET变量统一改名为NEXT_PUBLIC_SANITY_DATASET_ID(注意末尾追加了_ID)。

如果直接搜索NEXT_PUBLIC_SANITY_DATASET,会返回一大堆已经改过名的结果,难以定位“还剩下哪些旧变量”。笔记给出的方案是使用正则的负向前瞻(negative look-ahead),匹配“后面不跟_ID”的旧变量:

$ rg --pcre2 'NEXT_PUBLIC_SANITY_DATASET(?!_ID)' --hidden --glob '!node_modules/**' --glob '!.git/**'

关键点在于:默认的 ripgrep 正则引擎(Rust 正则库)不支持 look-around,直接执行会报regex parse error,错误信息会明确提示需要使用--pcre2标志;加上--pcre2后,就可以精确列出所有仍在使用旧变量名的文件与行号,例如.env.development中的NEXT_PUBLIC_SANITY_DATASET=production。

这个场景恰好展示了NEXT_PUBLIC_变量常见的生命周期:它们广泛散落在.env*配置文件、服务端脚本和前端代码中,重命名或迁移时需要精确的检索手段。

实战检查清单

综合本文内容,使用NEXT_PUBLIC_变量时建议遵循以下清单:

  1. 确认值非敏感:要公开的变量绝不能在浏览器 bundle 中泄露机密信息;
  2. 统一前缀命名:客户端需要读取的变量一律以NEXT_PUBLIC_开头,例如NEXT_PUBLIC_API_BASE_URL;
  3. 按环境拆分文件:在.env.development/.env.production(或带.local的优先级更高变体)中定义不同取值;
  4. 记住构建时替换:修改NEXT_PUBLIC_变量后必须重新构建(next build)并重新部署,浏览器端才会拿到新值;
  5. 服务端变量不加前缀:仅供服务端使用的密钥保持普通命名,避免误入客户端 bundle;
  6. 迁移时精确检索:批量重命名NEXT_PUBLIC_变量时,可用rg --pcre2配合负向前瞻只命中旧变量。

小结

Next.js 出于安全考虑默认不把环境变量打进客户端代码,process.env.API_BASE_URL在浏览器端返回undefined是预期行为而非 bug。要让非敏感变量公开可见,只需给变量名加上NEXT_PUBLIC_前缀,它就会被构建器静态内联进客户端 bundle,从而在页面、组件与服务端代码中统一通过process.env.NEXT_PUBLIC_*读取。结合 til 仓库中关于.env*加载顺序与 ripgrep 迁移的笔记,你可以在真实项目中正确组织、覆盖并维护这些公开环境变量。

  • 文档
  • 教程
  • 知识库

【免费下载链接】til

:memo: Today I Learned

项目地址:https://gitcode.com/gh_mirrors/ti/til
点击查看免费下载
上一篇:如何3步完成黑苹果智能配置:OpCore Simplify终极指南
下一篇:终极AtlasOS网络共享配置指南:3种方法快速恢复局域网文件共享

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 20:20:37

免解压免配置,Codex 三强版,AI Agent 办公落地实操

💡前言 很多朋友在 Windows 上体验桌面 AI 智能体时,常常会遇到任务执行黑盒化、修改无法追溯、缺少定时调度、插件扩展能力有限等问题。如果你已经试过同类工具,正在寻找一套稳定性更强、操作全程可审查、功能覆盖面更广的本地自动化方案&a…

作者头像 李华
网站建设 2026/10/7 20:19:51

Unity 2019.4.40f1c1 消息机制客户端:口袋精灵2毕设工程复现与避坑指南

简介:这份资源是面向高校学生与Unity初学者的本科毕业设计级项目工程,核心为基于消息机制的Unity客户端框架,开发环境为Unity 2019.4.40f1c1,玩法上基本复刻了已停运的网页游戏《口袋精灵2》。它适合用于毕业设计、课程设计、期末…

作者头像 李华
网站建设 2026/10/7 20:19:00

Codex 本地环境一键部署,Windows 与 macOS 双平台实操

前言 相信很多开发者在尝试 Codex 的时候,最大的障碍不是工具本身,而是前期环境部署。手动下载安装 Node.js,处理不同版本的依赖包,还要在终端输入多条命令,一旦出现版本冲突,排查问题就要耗费很久。 这款…

作者头像 李华