使用环境变量

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

¥Environment variable inputs are a vital part of your applications that you'll need to account for in your Turborepo configuration.

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

¥There are three important questions when working with environment variables in Turborepo:

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

¥Failing to account for environment variables in your configuration can result in shipping your application with the wrong configuration. This can cause serious issues like shipping your preview deployments to production.

Good to know: 

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

¥Turborepo also uses System Environment Variables to configure its own behavior. Below, you'll find information about environment variables for your task's runtime and how they affect task hashing.

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

¥Adding environment variables to task hashes

Turborepo 需要了解你的环境变量,以适应应用行为的变化。为此,请在你的 turbo.json 文件中使用 envglobalEnv 键。

¥Turborepo needs to be aware of your environment variables to account for changes in application behavior. To do this, use the env and globalEnv keys in your turbo.json file.

Turborepo logo
./turbo.json
{
  "globalEnv": ["IMPORTANT_GLOBAL_VARIABLE"],
  "tasks": {
    "build": {
      "env": ["MY_API_URL", "MY_API_KEY"]
    }
  }
}
  • globalEnv:更改此列表中任何环境变量的值都将更改所有任务的哈希值。

    ¥globalEnv: Changes to the values of any environment variables in this list will change the hash for all tasks.

  • env:包含对影响任务的环境变量值的更改,从而实现更好的粒度。例如,当 API_KEY 的值发生变化时,lint 任务可能不需要丢失缓存,但 build 任务可能需要。

    ¥env: Includes changes to the values of environment variables that affect the task, allowing for better granularity. For example, a lint task probably doesn't need to miss cache when the value of API_KEY changes, but a build task likely should.

Good to know: 

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

¥Turborepo supports wildcards for environment variables so you can easily account for all environment variables with a given prefix. Visit the API reference for env for more.

框架推断

¥Framework Inference

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

¥Turborepo automatically adds prefix wildcards to your env key for common frameworks. If you're using one of the frameworks below in a package, you don't need to specify environment variables with these prefixes:

Framework

env wildcards

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, LAUNCH_EDITOR
RedwoodJSREDWOOD_ENV_*
Sanity StudioSANITY_STUDIO_*
SolidVITE_*
SvelteKitVITE_*, PUBLIC_*
ViteVITE_*
VueVUE_APP_*, LAUNCH_EDITOR

Good to know: 

Framework inference is per-package.

如果你想退出框架推断,可以通过以下方式操作:

¥If you'd like to opt out of Framework Inference, you can do so by:

  • 使用 --framework-inference=false 运行你的任务

    ¥Running your tasks with --framework-inference=false

  • env 键中添加负通配符(例如 "env": ["!NEXT_PUBLIC_*"]

    ¥Adding a negative wildcard to the env key (for example, "env": ["!NEXT_PUBLIC_*"])

环境模式

¥Environment Modes

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

¥Turborepo's Environment Modes allow you to control which environment variables are available to a task at runtime:

  • 严格模式(默认):将环境变量过滤为仅在 turbo.json 中的 envglobalEnv 键中指定的变量。

    ¥Strict Mode (Default): Filter environment variables to only those that are specified in the env and globalEnv keys in turbo.json.

  • 松散模式:允许进程的所有环境变量可用。

    ¥Loose Mode: Allow all environment variables for the process to be available.

严格模式

¥Strict Mode

严格模式会将任务运行时可用的环境变量过滤为仅在 turbo.jsonglobalEnvenv 键中指定的变量。

¥Strict Mode filters the environment variables available to a task's runtime to only those that are specified in the globalEnv and env keys in turbo.json.

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

¥This means that tasks that do not account for all of the environment variables that they need are likely to fail. This is a good thing, since you don't want to cache a task that can potentially have different behavior in a different environment.

Cache safety with Strict Mode

虽然严格模式在你未考虑所有环境变量的情况下更容易导致任务失败,但它并不能保证任务一定会失败。如果你的应用能够妥善处理缺失的环境变量,你仍然可以成功完成任务并获得意外的缓存命中。

¥While Strict Mode makes it much more likely for your task to fail when you haven't accounted for all of your environment variables, it doesn't guarantee task failure. If your application is able to gracefully handle a missing environment variable, you could still successfully complete tasks and get unintended cache hits.

传递变量

¥Passthrough variables

在高级用例中,你可能希望将某些环境变量提供给任务,但不将它们包含在哈希值中。更改这些变量不会影响任务输出,但仍需要这些变量才能使任务成功运行。

¥In advanced use cases, you may want to make some environment variables available to a task without including them in the hash. Changes to these variables don't affect task outputs but still need to be available for the task to run successfully.

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

¥For these cases, add those environment variables to globalPassThroughEnv and passThroughEnv.

CI 供应商兼容性

¥CI vendor compatibility

严格模式将过滤掉来自 CI 供应商的环境变量,直到你使用 envglobalEnvpassThroughEnvglobalPassThroughEnv 对其进行处理。

¥Strict Mode will filter out environment variables that come from your CI vendors until you've accounted for them using env, globalEnv, passThroughEnv, or globalPassThroughEnv.

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

¥If any of these variables are important to your tasks and aren't included by Framework Inference, make sure they are in your turbo.json configuration.

松散模式

¥Loose Mode

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

¥Loose Mode does not filter your environment variables according to your globalEnv and env keys. This makes it easier to get started with incrementally migrating to Strict Mode.

使用 --env-mode 标志 在任何调用中启用松散模式,如果你发现脚本无法找到环境变量:

¥Use the --env-mode flag to enable Loose Mode on any invocation where you're seeing environment variables cannot be found by your scripts:

Terminal
turbo run build --env-mode=loose

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

¥As long as the environment variable is available when turbo is ran, your script will be able to use it. However, this also lets you accidentally forget to account for an environment variable in your configuration much more easily, allowing the task to hit cache when it shouldn't.

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

¥For example, you may have some code in your application that fetches data from an API, using an environment variable for the base 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

¥You then build your application using a value for MY_API_URL that targets your preview environment. When you're ready to ship your application, you build for production and see a cache hit - even though the value of the MY_API_URL variable has changed! MY_API_URL changed - but Turborepo restored a version of your application from cache that uses the preview environment's MY_API_URL rather than production's.

当你使用松散模式时,即使 MY_API_URL 未包含在任务哈希中,它也可以在任务运行时中使用。为了使此任务更容易失败并保护你免受此错误配置的影响,我们建议你选择 严格模式

¥When you're using Loose Mode, MY_API_URL is available in the task runtime even though it isn't accounted for in the task hash. To make this task more likely to fail and protect you from this misconfiguration, we encourage you to opt for Strict Mode.

平台环境变量

¥Platform Environment Variables

将应用部署到 Vercel 时,你可能已经在项目中配置了 环境变量。Turborepo 会自动根据你 turbo.json 的配置检查这些变量,以确保你已安装 已说明,并会在缺少任何变量时触发警告。

¥When deploying your application to Vercel, you likely already have environment variables configured on your project. Turborepo will automatically check these variables against your turbo.json configuration to ensure that you've accounted for them, and will warn you about any missing variables.

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

¥This functionality can be disabled by setting TURBO_PLATFORM_ENV_DISABLED=false

处理 .env 文件

¥Handling .env files

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

¥.env files are great for working on an application locally. Turborepo does not load .env files into your task's runtime, leaving them to be handled by your framework, or tools like dotenv.

但是,让 turbo 知道 .env 文件中值的更改非常重要,这样它才能使用它们进行哈希处理。如果你在构建之间更改了 .env 文件中的变量,build 任务将无法缓存。

¥However, it's important that turbo knows about changes to values in your .env files so that it can use them for hashing. If you change a variable in your .env files between builds, the build task should miss cache.

为此,请将文件添加到 inputs 键:

¥To do this, add the files to the inputs key:

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

多个 .env 文件

¥Multiple .env files

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

¥You can capture multiple .env files at once using a *.

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 files can load variables into the task runtime even when the environment variables have not been added to the env key. Ensure that you add your environment variables for your builds the env key for CI and production builds.

最佳实践

¥Best practices

在软件包中使用 .env 文件

¥Use .env files in packages

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

¥Using a .env file at the root of the repository is not recommended. Instead, we recommend placing your .env files into the packages where they're used.

由于环境变量在每个应用的运行时中都单独存在,因此这种做法可以更紧密地模拟应用的运行时行为。此外,随着 monorepo 的扩展,这种做法可以更轻松地管理每个应用的环境,防止跨应用的环境变量泄漏。

¥This practice more closely models the runtime behavior of your applications since environment variables exist in each application's runtime individually. Additionally, as your monorepo scales, this practice makes it easier to manage each application's environment, preventing environment variable leakage across applications.

Good to know: 

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

¥You may find it easier to use a root .env file when incrementally migrating to a monorepo. Tools like dotenv can load .env files from different locations.

使用 eslint-config-turbo

¥Use eslint-config-turbo

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

¥The eslint-config-turbo package helps you find environment variables that are used in your code that aren't listed in your turbo.json. This helps ensure that all your environment variables are accounted for in your configuration.

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

¥Avoid creating or mutating environment variables at runtime

Turborepo 会在任务开始时对任务的环境变量进行哈希处理。如果你在任务期间创建或修改了环境变量,Turborepo 将无法感知这些更改,也不会在任务哈希中记录它们。

¥Turborepo hashes the environment variables for your task at the beginning of the task. If you create or mutate environment variables during the task, Turborepo will not know about these changes and will not account for them in the task hash.

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

¥For instance, Turborepo will not be able to detect the inline variable in the example below:

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

MY_VARIABLE 是在 dev 任务启动后添加到环境中的,因此 turbo 将无法使用它进行哈希计算。

¥MY_VARIABLE is being added to the environment after the dev task has started, so turbo will not be able to use it for hashing.

示例

¥Examples

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

¥Below are examples of proper environment variable configuration for a few popular frameworks:

故障排除

¥Troubleshooting

使用 --summarize

¥Use --summarize

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

¥The --summarize flag can be added to your turbo run command to produce a JSON file summarizing data about your task. Checking the diff for the globalEnv and env key can help you identify any environment variables that may be missing from your configuration.

后续步骤

¥Next steps

设置好环境变量后,你就可以开始构建 CI 流水线了,以 turbo 的速度构建、检查和部署你的应用。

¥Once you've accounted for your environment variables, you're ready to start building the CI pipelines that build, check, and deploy your applications, at the speed of turbo.