使用环境变量

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

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

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

须知: 

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

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

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

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

须知: 

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

框架推断

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

框架

env 通配符

AstroPUBLIC_*
BlitzNEXT_PUBLIC_*
Create React AppREACT_APP_*
GatsbyGATSBY_*
Next.jsNEXT_PUBLIC_*
NitroNITRO_*, SERVER_*, AWS_APP_ID, INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN, CLEAVR, CF_PAGES, FIREBASE_APP_HOSTING, NETLIFY, STORMKIT, NOW_BUILDER, ZEABUR, RENDER
Nuxt.jsNUXT_*, NITRO_*, SERVER_*, AWS_APP_ID, INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN, CLEAVR, CF_PAGES, FIREBASE_APP_HOSTING, NETLIFY, STORMKIT, NOW_BUILDER, ZEABUR, RENDER
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

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

多个 .env 文件

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

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

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

最佳实践

在包中使用 .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_VARIABLEdev 任务启动被添加到环境中,因此 turbo 将无法使用它进行哈希处理。

示例

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

故障排除

使用 --summarize

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

下一步

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