环境变量

本文档适用于 9.4 和更高版本的 Next.js。如果你使用的是较旧版本的 Next.js,请参阅 next.config.js 中的环境变量

示例

Next.js 内置了对环境变量的支持,让你可以执行以下操作:

加载环境变量

Next.js 内置支持将环境变量从 .env.local 加载到 process.env 中。

一个 .env.local 文件示例:

DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword

这回将 process.env.DB_HOSTprocess.env.DB_USERprocess.env.DB_PASS 自动加载到 Node.js 环境中,从而允许你在 Next.js 的数据提取方法API 路由 中使用它们。

例如,在 getStaticProps 中:

// pages/index.js
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.js 将在构建时会将 process.env.* 替换为对应的值。 这就意味着 process.env 不是标准的 JavaScript 对象,因此你不能对其 使用 对象解构(object destructuring) 语法。 环境变量应当以类似 process.env.PUBLISHABLE_KEY 方式访问,而 不能const { PUBLISHABLE_KEY } = process.env 方式。

注意: Next.js 会在 .env* 文件中自动扩展变量(例如 $VAR)。 这允许你访问其它的密钥类信息,如下所示:

# .env
HOSTNAME=localhost
PORT=8080
HOST=http://$HOSTNAME:$PORT

如果你尝试使用实际值中带有 $ 符号的变量,则需要像这样 \$ 对其进行转义。

例如:

# .env
A=abc

# 扩展为 "preabc"
WRONG=pre$A

# 扩展为 "pre$A"
CORRECT=pre\$A

将环境变量暴露给浏览器

默认情况下,环境变量仅在 Node.js 环境中可用,这意味着它们不会暴露到浏览器端。

为了向浏览器暴露环境变量,你必须在变量前添加 NEXT_PUBLIC_ 前缀。例如:

NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk

这将自动将 process.env.NEXT_PUBLIC_ANALYTICS_ID 加载到 Node.js 环境中,从而允许你在代码的任何地方使用它。带有前缀 NEXT_PUBLIC_ 的变量将被内联到发送给浏览器的 JavaScript 代码中。由于这种内联发生在构建时,因此在构建项目时需要设置好各个 NEXT_PUBLIC_ 前缀的环境变量。

// pages/index.js
import setupAnalyticsService from '../lib/my-analytics-service'

// NEXT_PUBLIC_ANALYTICS_ID can be used here as it's prefixed by NEXT_PUBLIC_
setupAnalyticsService(process.env.NEXT_PUBLIC_ANALYTICS_ID)

function HomePage() {
  return <h1>Hello World</h1>
}

export default HomePage

默认环境变量

通常只需要一个 .env.local 文件就够了。但是,有时你可能希望分别为 development (next dev) 或 production (next start) 环境添加一些默认设置。

Next.js允许你在 .env (所有环境下)、.env.development (development 环境)和 .env.production (production 环境) 中设置默认值。

.env.local 始终覆盖默认设置。

注意:由于 .env.env.development.env.production 文件定义了默认设置,因此应该提交到源码仓库中。而 .env.*.local 应当添加到 .gitignore 中,因为这类文件是需要被忽略的。.env.local 是被用来存储密钥类信息的。

Environment Variables on Vercel

When deploying your Next.js application to Vercel, Environment Variables can be configured in the Project Settings.

All types of Environment Variables should be configured there. Even Environment Variables used in Development – which can be downloaded onto your local device afterwards.

If you've configured Development Environment Variables you can pull them into a .env.local for usage on your local machine using the following command:

vercel env pull .env.local

When using the Vercel CLI to deploy make sure you add a .vercelignore that includes files that should not be uploaded, generally these are the same files included in .gitignore.

测试环境变量

除了 developmentproduction 环境,还有第三个环境: test。与为 development 和 production 环境设置默认值类似,你可以使用 .env.test 为 test 环境设置变量(尽管此文件并不如前两个文件常见)。

当使用 jestcypress 之类的工具运行测试用例时,此功能将非常有用,你只需要为测试目的而设置特定的环境变量即可。如果 NODE_ENV 被设置为 test,则加载相应的默认值,因为测试工具会为你自动加载,因此通常不需要手动执行此操作。

test 环境与 developmentproduction 环境之间存在细微的差别:.env.local 不会被加载,因为你的预期是没跟人运行测试用例都会有相同的结果。因此,通过忽略.env.local(旨在覆盖默认设置),每个测试在执行时都将使用相同的默认值。

注意: 与默认环境变量类似,.env.test 文件应提交到源码仓库中,但 .env.test.local 就不需要了提交了,因为 .env*.local 是需要通过 .gitignore 来忽略的文件。

在运行单元测试时,可以通过使用 @next/env 软件包的 loadEnvConfig 函数,来确保采用与 Next.js 相同的方式加载环境变量。

// 以下内容可用于 Jest 全局配置文件或类似的测试配置中
import { loadEnvConfig } from '@next/env'

export default async () => {
  const projectDir = process.cwd()
  loadEnvConfig(projectDir)
}