Turborepo logo

使用环境变量

环境变量输入是你应用程序的重要组成部分,你需要在 Turborepo 配置中考虑它们。

在 Turborepo 中使用环境变量时,有三个重要问题

未能考虑配置中的环境变量可能会导致你的应用程序以错误的配置发布。这可能会导致严重问题,例如将你的预览部署发布到生产环境。

须知: 

Turborepo 还使用系统环境变量来配置其自身的行为。在下面,你将找到关于你的任务运行时的环境变量以及它们如何影响任务哈希的信息。

将环境变量添加到任务哈希

Turborepo 需要知道你的环境变量,以便考虑应用程序行为的更改。为此,请在你的 turbo.json 文件中使用 envglobalEnv 键。

./turbo.json
{
  "globalEnv": ["IMPORTANT_GLOBAL_VARIABLE"],
  "tasks": {
    "build": {
      "env": ["MY_API_URL", "MY_API_KEY"]
    }
  }
}
  • globalEnv:此列表中任何环境变量值的更改都将更改所有任务的哈希值。
  • env:包括影响任务的环境变量值的更改,从而实现更好的粒度。例如,当 API_KEY 的值更改时,lint 任务可能不需要错过缓存,但 build 任务很可能应该错过缓存。

须知: 

Turborepo 支持环境变量的通配符,因此你可以轻松地考虑具有给定前缀的所有环境变量。访问 env 的 API 参考以了解更多信息。

框架推断

Turborepo 会自动将前缀通配符添加到你的 env 键中,用于常见框架。如果你在一个包中使用以下框架之一,则无需指定具有这些前缀的环境变量

框架

env 通配符

AstroPUBLIC_*
BlitzNEXT_PUBLIC_*
Create React AppREACT_APP_*
GatsbyGATSBY_*
Next.jsNEXT_PUBLIC_*
NitroNITRO_*
Nuxt.jsNUXT_*, NITRO_*
RedwoodJSREDWOOD_ENV_*
Sanity StudioSANITY_STUDIO_*
SolidVITE_*
SvelteKitVITE_*, PUBLIC_*
ViteVITE_*
VueVUE_APP_*

须知: 

框架推断是按包进行的。

如果你想选择退出框架推断,你可以通过以下方式进行

  • 使用 --framework-inference=false 运行你的任务
  • env 键添加负通配符(例如,"env": ["!NEXT_PUBLIC_*"]

环境模式

Turborepo 的环境模式允许你控制哪些环境变量在运行时可用于任务

  • 严格模式(默认):过滤环境变量,保留在 turbo.json 文件中的 envglobalEnv 键中指定的那些。
  • 宽松模式:允许所有进程的环境变量都可用。

严格模式

严格模式过滤可用于任务运行时的环境变量,保留在 turbo.json 文件中的 globalEnvenv 键中指定的那些。

这意味着未考虑其所需的所有环境变量的任务很可能会失败。这是一件好事,因为你不想缓存可能在不同环境中具有不同行为的任务。

严格模式下的缓存安全性

虽然严格模式使你在未考虑所有环境变量时更可能使任务失败,但它不能保证任务失败。如果你的应用程序能够优雅地处理丢失的环境变量,你仍然可以成功完成任务并获得意外的缓存命中。

透传变量

在高级用例中,你可能希望使某些环境变量可用于任务,而无需将其包含在哈希中。这些变量的更改不会影响任务输出,但仍然需要可用于任务成功运行。

对于这些情况,请将这些环境变量添加到 globalPassThroughEnvpassThroughEnv 中。

CI 供应商兼容性

严格模式将过滤掉来自你的 CI 供应商的环境变量,直到你使用 envglobalEnvpassThroughEnvglobalPassThroughEnv 考虑它们。

如果这些变量中的任何一个对你的任务很重要,并且未被框架推断包含,请确保它们在你的 turbo.json 配置中。

宽松模式

宽松模式不根据你的 globalEnvenv 键过滤你的环境变量。这使得更容易开始逐步迁移到严格模式。

使用 --env-mode 标志 在任何你看到脚本找不到环境变量的调用中启用宽松模式

终端
turbo run build --env-mode=loose

只要环境变量在 turbo 运行的时候可用,你的脚本将能够使用它。但是,这也让你更容易意外地忘记在你的配置中考虑环境变量,从而允许任务在不应该缓存时命中缓存。

例如,你的应用程序中可能有某些代码从 API 获取数据,并使用环境变量作为基本 URL

./apps/web/data-fetcher.ts
const data = fetch(`${process.env.MY_API_URL}/resource/1`);

然后,你使用针对你的预览环境的 MY_API_URL 值构建你的应用程序。当你准备发布你的应用程序时,你为生产环境构建并看到缓存命中 - 即使 MY_API_URL 变量的值已更改!MY_API_URL 已更改 - 但 Turborepo 从缓存中恢复了应用程序的版本,该版本使用预览环境的 MY_API_URL 而不是生产环境的。

当你使用宽松模式时,MY_API_URL 在任务运行时可用,即使它没有在任务哈希中被考虑。为了使此任务更有可能失败并保护你免受此错误配置的影响,我们鼓励你选择严格模式

平台环境变量

当将你的应用程序部署到 Vercel 时,你可能已经配置了项目上的环境变量。Turborepo 将自动检查这些变量与你的 turbo.json 配置,以确保你已考虑了它们,并将警告你任何缺失的变量。

可以通过设置 TURBO_PLATFORM_ENV_DISABLED=false 来禁用此功能

处理 .env 文件

.env 文件非常适合在本地处理应用程序。Turborepo 不会将 .env 文件加载到你的任务运行时中,而是让你的框架或 dotenv 等工具来处理它们。

但是,重要的是 turbo 知道你的 .env 文件中值的更改,以便它可以将它们用于哈希。如果你在构建之间更改了 .env 文件中的变量,则 build 任务应该错过缓存。

为此,请将文件添加到 inputs

./turbo.json
{
  "globalDependencies": [".env"], // All task hashes
  "tasks": {
    "build": {
      "inputs": ["$TURBO_DEFAULT$", ".env"] // Only the `build` task hash
    }
  }
}

多个 .env 文件

你可以使用 * 一次捕获多个 .env 文件。

./turbo.json
{
  "globalDependencies": [".env"], // All task hashes
  "tasks": {
    "build": {
      "inputs": ["$TURBO_DEFAULT$", ".env*"] // Only the `build` task hash
    }
  }
}

即使环境变量尚未添加到 env.env 文件也可以将变量加载到任务运行时中。确保你为你的构建将环境变量添加到 env 键中,用于 CI 和生产构建。

最佳实践

在包中使用 .env 文件

不建议在仓库的根目录中使用 .env 文件。相反,我们建议将你的 .env 文件放置在使用它们的包中。

这种做法更紧密地模拟了你的应用程序的运行时行为,因为环境变量单独存在于每个应用程序的运行时中。此外,随着你的 monorepo 扩展,这种做法使管理每个应用程序的环境变得更容易,防止了跨应用程序的环境变量泄漏。

须知: 

当你逐步迁移到 monorepo 时,你可能会发现使用根 .env 文件更容易。像 dotenv 这样的工具可以从不同的位置加载 .env 文件。

使用 eslint-config-turbo

eslint-config-turbo 帮助你查找在你的代码中使用但未在你的 turbo.json 中列出的环境变量。这有助于确保你的所有环境变量都在你的配置中被考虑。

避免在运行时创建或更改环境变量

Turborepo 在任务开始时哈希你的任务的环境变量。如果你在任务期间创建或更改环境变量,Turborepo 将不知道这些更改,并且不会在任务哈希中考虑它们。

例如,Turborepo 将无法检测到下面示例中的内联变量

./apps/web/package.json
{
  "scripts": {
    "dev": "export MY_VARIABLE=123 && next dev"
  }
}

MY_VARIABLE 是在 dev 任务启动添加到环境中的,因此 turbo 将无法将其用于哈希。

示例

以下是一些流行的框架的正确环境变量配置示例

故障排除

使用 --summarize

可以将 --summarize 标志 添加到你的 turbo run 命令中,以生成一个 JSON 文件,其中汇总了有关你的任务的数据。检查 globalEnvenv 键的差异可以帮助你识别配置中可能缺少的任何环境变量。

下一步

一旦你考虑了你的环境变量,你就可以开始构建 CI 管道,以 turbo 的速度构建、检查和部署你的应用程序。