使用环境变量

环境变量输入是应用程序的重要组成部分,您需要在 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:包括影响任务的环境变量值的更改,从而实现更好的粒度。例如,lint 任务可能不需要在 API_KEY 的值更改时错过缓存,但 build 任务很可能需要。

须知: 

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

框架推断

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

框架

env 通配符

AstroPUBLIC_*
BlitzNEXT_PUBLIC_*
Create React AppREACT_APP_*
ExpoEXPO_PUBLIC_*
GatsbyGATSBY_*
Next.jsNEXT_PUBLIC_*
NitroNITRO_*SERVER_*AWS_APP_IDINPUT_AZURE_STATIC_WEB_APPS_API_TOKENCLEAVRCF_PAGESFIREBASE_APP_HOSTINGNETLIFYSTORMKITNOW_BUILDERZEABURRENDER
Nuxt.jsNUXT_*NITRO_*SERVER_*AWS_APP_IDINPUT_AZURE_STATIC_WEB_APPS_API_TOKENCLEAVRCF_PAGESFIREBASE_APP_HOSTINGNETLIFYSTORMKITNOW_BUILDERZEABURRENDERLAUNCH_EDITOR
RedwoodJSREDWOOD_ENV_*
Sanity StudioSANITY_STUDIO_*
SolidVITE_*
SvelteKitVITE_*PUBLIC_*
ViteVITE_*
VueVUE_APP_*LAUNCH_EDITOR

须知: 

框架推断是每个包独立的。

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

  • 使用 --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 已更改,但 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 文件放在它们被使用的包中。

这种做法更紧密地模拟了应用程序的运行时行为,因为环境变量单独存在于每个应用程序的运行时中。此外,随着您的单体仓库扩展,这种做法可以更轻松地管理每个应用程序的环境,防止应用程序之间的环境变量泄露。

须知: 

在增量迁移到单体仓库时,您可能会发现使用根目录的 .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 的速度构建、检查和部署您的应用程序。