如何在 Next.js 中使用环境变量
Next.js 内置了对环境变量的支持,这允许你执行以下操作
警告: 默认的
create-next-app
模板确保所有.env
文件都添加到你的.gitignore
中。你几乎从不希望将这些文件提交到你的仓库。
加载环境变量
Next.js 内置支持将 .env*
文件中的环境变量加载到 process.env
中。
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
这会自动将 process.env.DB_HOST
、process.env.DB_USER
和 process.env.DB_PASS
加载到 Node.js 环境中,允许你在 Next.js 数据获取方法 和 API 路由中使用它们。
例如,使用 getStaticProps
export async function getStaticProps() {
const db = await myDB.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS,
})
// ...
}
使用 @next/env
加载环境变量
如果你需要在 Next.js 运行时之外加载环境变量,例如在 ORM 或测试运行器的根配置文件中,你可以使用 @next/env
包。
Next.js 内部使用此包从 .env*
文件加载环境变量。
要使用它,请安装该包并使用 loadEnvConfig
函数加载环境变量
npm install @next/env
import { loadEnvConfig } from '@next/env'
const projectDir = process.cwd()
loadEnvConfig(projectDir)
然后,你可以根据需要导入配置。例如
import './envConfig.ts'
export default defineConfig({
dbCredentials: {
connectionString: process.env.DATABASE_URL!,
},
})
引用其他变量
Next.js 会自动展开在 .env*
文件中使用 $
引用其他变量(例如 $VARIABLE
)的变量。这允许你引用其他秘密。例如
TWITTER_USER=nextjs
TWITTER_URL=https://x.com/$TWITTER_USER
在上面的示例中,process.env.TWITTER_URL
将设置为 https://x.com/nextjs
。
须知: 如果你需要在实际值中使用带
$
的变量,它需要被转义,例如\$
。
为浏览器打包环境变量
非 NEXT_PUBLIC_
环境变量仅在 Node.js 环境中可用,这意味着它们无法在浏览器(客户端在不同的 环境 中运行)中访问。
为了使环境变量的值在浏览器中可访问,Next.js 可以在构建时将值“内联”到交付给客户端的 js 包中,将所有对 process.env.[variable]
的引用替换为硬编码值。要指示它执行此操作,你只需将变量前缀为 NEXT_PUBLIC_
。例如
NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk
这将告诉 Next.js 将 Node.js 环境中所有对 process.env.NEXT_PUBLIC_ANALYTICS_ID
的引用替换为你运行 next build
时的环境值,从而允许你在代码中的任何位置使用它。它将被内联到发送到浏览器的任何 JavaScript 中。
注意:构建后,你的应用程序将不再响应这些环境变量的更改。例如,如果你使用 Heroku 管道将一个环境中构建的 slug 提升到另一个环境,或者你构建并部署一个 Docker 镜像到多个环境,所有
NEXT_PUBLIC_
变量都将冻结为构建时评估的值,因此这些值需要在项目构建时适当设置。如果你需要访问运行时环境变量值,你必须设置自己的 API 来将它们提供给客户端(按需或在初始化期间)。
import setupAnalyticsService from '../lib/my-analytics-service'
// 'NEXT_PUBLIC_ANALYTICS_ID' can be used here as it's prefixed by 'NEXT_PUBLIC_'.
// It will be transformed at build time to `setupAnalyticsService('abcdefghijk')`.
setupAnalyticsService(process.env.NEXT_PUBLIC_ANALYTICS_ID)
function HomePage() {
return <h1>Hello World</h1>
}
export default HomePage
请注意,动态查找将**不会**被内联,例如
// This will NOT be inlined, because it uses a variable
const varName = 'NEXT_PUBLIC_ANALYTICS_ID'
setupAnalyticsService(process.env[varName])
// This will NOT be inlined, because it uses a variable
const env = process.env
setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID)
运行时环境变量
Next.js 可以支持构建时和运行时环境变量。
默认情况下,环境变量仅在服务器上可用。要将环境变量暴露给浏览器,必须使用 NEXT_PUBLIC_
前缀。但是,这些公共环境变量将在 next build
期间内联到 JavaScript 包中。
要读取运行时环境变量,我们建议使用 getServerSideProps
或逐步采用 App Router。
这允许您使用单个 Docker 镜像,该镜像可以通过具有不同值的多个环境进行推广。
须知
- 您可以使用
register
函数在服务器启动时运行代码。
测试环境变量
除了 development
和 production
环境之外,还有第三个选项:test
。你可以像为开发或生产环境设置默认值一样,使用 .env.test
文件为 testing
环境设置默认值(尽管这个不如前两个常见)。Next.js 在 testing
环境中不会从 .env.development
或 .env.production
加载环境变量。
当使用 jest
或 cypress
等工具运行测试时,这很有用,因为你只需要为测试目的设置特定的环境变量。如果 NODE_ENV
设置为 test
,则会加载测试默认值,尽管你通常不需要手动执行此操作,因为测试工具会为你处理。
test
环境与 development
和 production
之间有一个小区别,你需要记住:.env.local
不会被加载,因为你期望测试为每个人产生相同的结果。这样,每次测试执行都会通过忽略你的 .env.local
(它旨在覆盖默认设置)来使用相同的环境默认值。
须知:类似于默认环境变量,
.env.test
文件应包含在你的仓库中,但.env.test.local
不应包含,因为.env*.local
旨在通过.gitignore
忽略。
在运行单元测试时,你可以利用 @next/env
包中的 loadEnvConfig
函数,确保以 Next.js 相同的方式加载环境变量。
// The below can be used in a Jest global setup file or similar for your testing set-up
import { loadEnvConfig } from '@next/env'
export default async () => {
const projectDir = process.cwd()
loadEnvConfig(projectDir)
}
环境变量加载顺序
环境变量按以下顺序查找,一旦找到变量即停止。
process.env
.env.$(NODE_ENV).local
.env.local
(当NODE_ENV
为test
时不检查。).env.$(NODE_ENV)
.env
例如,如果 NODE_ENV
是 development
并且你在 .env.development.local
和 .env
中都定义了一个变量,则将使用 .env.development.local
中的值。
须知:
NODE_ENV
允许的值是production
、development
和test
。
须知
- 如果你使用的是
/src
目录,.env.*
文件应保留在项目根目录中。 - 如果环境变量
NODE_ENV
未分配,Next.js 在运行next dev
命令时自动分配development
,对于所有其他命令则分配production
。
版本历史
版本 | 更改 |
---|---|
v9.4.0 | 引入了对 .env 和 NEXT_PUBLIC_ 的支持。 |
这有帮助吗?