Next.js 环境变量
环境变量
以 NEXT_PUBLIC_
开头的环境变量才能被客户端访问,其他环境变量只能在服务端使用。
NOTE
我们注意到,客户端也可以直接访问 process.env.NEXT_PUBLIC_XXX
,因为 Next.js 会在构建时将这些代码替换为内联值,因此它们也不能在构建之后改变。
这种替换方法不能用于动态访问,例如客户端不能使用下面的代码:
const varName = 'NEXT_PUBLIC_ANALYTICS_ID'
setupAnalyticsService(process.env[varName])
const env = process.env
setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID)
在服务端,我们可以通过 process.env.NODE_ENV
来判断当前环境,开发环境为 'development'
,而生产环境为 'production'
。
如果我们希望在客户端也能获取到当前环境,则需要自定义环境变量。我们可以通过在 .env.development
文件中添加 NEXT_PUBLIC_ENV=development
来实现。然后我们读取 process.env.NEXT_PUBLIC_ENV
来获取当前环境。
如果我们希望自定义一种环境,比如 staging
或者 preview
,则它最好由 development
衍生,这样我们可以在开发环境中模拟这种环境。
构建时
还有一种特殊的状态,叫做构建时(buildtime),这和运行时(runtime)或生产环境有一些不同,例如当我们的服务端页面需要预渲染时,我们需要在构建时生成静态页面。
在 Next.js 中,我们可以通过 process.env.NEXT_PHASE
来判断当前是否为构建时,为 true
则表示为构建时。
例如,当我们需要使用 Redis 时,我们一般这么用:
import { createClient } from 'redis'
export const redisClient = createClient({
url: process.env.REDIS_URL,
})
await redisClient.connect()
构建时需要生产环境的 Redis 地址,而构建时未必能连接到生产环境的 Redis,如果这个时候构建会一直尝试连接直至失败(因为 Next.js 会在构建时执行你的代码)。这时候我们加上判断:
import { createClient } from 'redis'
export const redisClient = createClient({
url: process.env.REDIS_URL,
})
if (!process.env.NEXT_PHASE) {
await redisClient.connect()
} else {
console.warn('[Redis] building now, skip connecting!')
}
这在 Docker 这种隔离的构建环境中很有用。当然也可以在这个时候连接到其他可用 Redis 服务器。