Skip to content

使用环境变量

Astro 允许你访问 Vite 的内置环境变量支持,并包含一些 项目的默认环境变量,允许你访问当前项目的配置值(例如 sitebase),无论你的项目是在开发中还是在生产中运行,等等。

¥Astro gives you access to Vite’s built-in environment variables support and includes some default environment variables for your project that allow you to access configuration values for your current project (e.g. site, base), whether your project is running in development or production, and more.

Astro 还提供了一种 使用和组织具有类型安全性的环境变量 的方法。它可用于 Astro 上下文(例如 Astro 组件、路由和端点、UI 框架组件、中间件)内,并使用 Astro 配置中的模式 进行管理。

¥Astro also provides a way to use and organize your environment variables with type safety. It is available for use inside the Astro context (e.g. Astro components, routes and endpoints, UI framework components, middleware), and managed with a schema in your Astro configuration.

¥Vite’s built-in support

Astro 使用 Vite 内置的环境变量支持,这些变量在构建时被静态替换,并允许你使用它们。

¥Astro uses Vite’s built-in support for environment variables, which are statically replaced at build time, and lets you use any of its methods to work with them.

请注意,虽然所有环境变量在服务器端代码中都可用,但出于安全目的,只有前缀为 PUBLIC_ 的环境变量在客户端代码中可用。

¥Note that while all environment variables are available in server-side code, only environment variables prefixed with PUBLIC_ are available in client-side code for security purposes.

.env
SECRET_PASSWORD=password123
PUBLIC_ANYBODY=there

在此示例中,PUBLIC_ANYBODY(可通过 import.meta.env.PUBLIC_ANYBODY 访问)将在服务器或客户端代码中可用,而 SECRET_PASSWORD(可通过 import.meta.env.SECRET_PASSWORD 访问)仅在服务器端可用。

¥In this example, PUBLIC_ANYBODY (accessible via import.meta.env.PUBLIC_ANYBODY) will be available in server or client code, while SECRET_PASSWORD (accessible via import.meta.env.SECRET_PASSWORD) will be server-side only.

TypeScript 的智能感知

标题部分 TypeScript 的智能感知

¥IntelliSense for TypeScript

默认情况下,Astro 在 astro/client.d.ts 中为 import.meta.env 提供了类型定义。

¥By default, Astro provides a type definition for import.meta.env in astro/client.d.ts.

虽然你可以在 .env.[mode] 文件中定义更多自定义环境变量,但你可能希望为前缀为 PUBLIC_ 的用户定义环境变量获取 TypeScript IntelliSense。

¥While you can define more custom env variables in .env.[mode] files, you may want to get TypeScript IntelliSense for user-defined env variables which are prefixed with PUBLIC_.

为此,你可以在 src/ 中创建 env.d.ts 并配置 ImportMetaEnv,如下所示:

¥To achieve this, you can create an env.d.ts in src/ and configure ImportMetaEnv like this:

src/env.d.ts
interface ImportMetaEnv {
readonly DB_PASSWORD: string;
readonly PUBLIC_POKEAPI: string;
// more env variables...
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

¥Default environment variables

Astro 包含一些开箱即用的环境变量:

¥Astro includes a few environment variables out of the box:

  • import.meta.env.MODE:你的网站运行的模式。运行 astro dev 时为 development,运行 astro build 时为 production

  • import.meta.env.PRODtrue(如果你的站点正在生产中运行);否则为 false

  • import.meta.env.DEVtrue(如果你的网站正在开发中);否则为 false。始终与 import.meta.env.PROD 相反。

  • import.meta.env.BASE_URL:你的网站正在从中提供服务的基本 URL。这是由 base 配置选项 决定的。

  • import.meta.env.SITE:这被设置为项目的 astro.config 中指定的 site 选项

  • import.meta.env.ASSETS_PREFIX:如果设置了 build.assetsPrefix config option,则为 Astro 生成的资源链接的前缀。这可用于创建 Astro 不处理的资源链接。

像任何其他环境变量一样使用它们。

¥Use them like any other environment variable.

const isProd = import.meta.env.PROD;
const isDev = import.meta.env.DEV;

¥Setting environment variables

¥.env files

环境变量可以从项目目录中的 .env 文件加载。

¥Environment variables can be loaded from .env files in your project directory.

只需在项目目录中创建一个 .env 文件并添加一些变量即可。

¥Just create a .env file in the project directory and add some variables to it.

.env
# This will only be available when run on the server!
DB_PASSWORD="foobar"
# This will be available everywhere!
PUBLIC_POKEAPI="https://pokeapi.co/api/v2"

你还可以将 .production.development 或自定义模式名称添加到文件名本身(例如 env.testing.env.staging)。这允许你在不同时间使用不同的环境变量集。

¥You can also add .production, .development or a custom mode name to the filename itself (e.g env.testing, .env.staging). This allows you to use different sets of environment variables at different times.

astro devastro build 命令分别默认为 "development""production" 模式。你可以使用 --mode 标志 运行这些命令,为 mode 传递不同的值并加载匹配的 .env 文件。

¥The astro dev and astro build commands default to "development" and "production" modes, respectively. You can run these commands with the --mode flag to pass a different value for mode and load the matching .env file.

这允许你运行开发服务器或构建连接到不同 API 的站点:

¥This allows you to run the dev server or build your site connecting to different APIs:

终端窗口
# Run the dev server connected to a "staging" API
astro dev --mode staging
# Build a site that connects to a "production" API with additional debug information
astro build --devOutput
# Build a site that connects to a "testing" API
astro build --mode testing

有关 .env 文件的更多信息,请参阅 参见 Vite 文档

¥For more on .env files, see the Vite documentation.

¥In the Astro config file

Astro 在加载其他文件之前会评估配置文件。这意味着你无法在 astro.config.mjs 中使用 import.meta.env 来访问在 .env 文件中设置的环境变量。

¥Astro evaluates configuration files before it loads your other files. This means that you cannot use import.meta.env in astro.config.mjs to access environment variables that were set in .env files.

你可以在配置文件中使用 process.env 来访问其他环境变量,例如 由 CLI 设置

¥You can use process.env in a configuration file to access other environment variables, like those set by the CLI.

你还可以使用 Vite 的 loadEnv 帮手 手动加载 .env 文件。

¥You can also use Vite’s loadEnv helper to manually load .env files.

astro.config.mjs
import { loadEnv } from "vite";
const { SECRET_PASSWORD } = loadEnv(process.env.NODE_ENV, process.cwd(), "");

¥Using the CLI

你还可以在运行项目时添加环境变量:

¥You can also add environment variables as you run your project:

终端窗口
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 npm run dev

¥Getting environment variables

Astro 中的环境变量通过 import.meta.env 访问,使用 import.meta feature added in ES2020,而不是 process.env。

¥Environment variables in Astro are accessed with import.meta.env, using the import.meta feature added in ES2020, instead of process.env.

例如,使用 import.meta.env.PUBLIC_POKEAPI 获取 PUBLIC_POKEAPI 环境变量。

¥For example, use import.meta.env.PUBLIC_POKEAPI to get the PUBLIC_POKEAPI environment variable.

// When import.meta.env.SSR === true
const data = await db(import.meta.env.DB_PASSWORD);
// When import.meta.env.SSR === false
const data = fetch(`${import.meta.env.PUBLIC_POKEAPI}/pokemon/squirtle`);

使用 SSR 时,可以根据所使用的 SSR 适配器在运行时访问环境变量。对于大多数适配器,你可以使用 process.env 访问环境变量,但某些适配器的工作方式有所不同。对于 Deno 适配器,你将使用 Deno.env.get()。了解如何在使用 Cloudflare 适配器时处理环境变量。Astro 将首先检查服务器环境中的变量,如果它们不存在,Astro 将在 .env 文件中查找它们。

¥When using SSR, environment variables can be accessed at runtime based on the SSR adapter being used. With most adapters you can access environment variables with process.env, but some adapters work differently. For the Deno adapter, you will use Deno.env.get(). See how to access the Cloudflare runtime to handle environment variables when using the Cloudflare adapter. Astro will first check the server environment for variables, and if they don’t exist, Astro will look for them in .env files.

¥Type safe environment variables

astro:env API 允许你为 你已设置的环境变量 配置类型安全模式。这允许你指示它们是否应该在服务器或客户端上可用,并定义它们的数据类型和附加属性。

¥The astro:env API lets you configure a type-safe schema for environment variables you have set. This allows you to indicate whether they should be available on the server or the client, and define their data type and additional properties.

Developing an adapter? See how to make an adapter compatible with astro:env.

¥Basic Usage

¥Define your schema

要配置模式,请将 env.schema 选项添加到你的 Astro 配置中:

¥To configure a schema, add the env.schema option to your Astro config:

astro.config.mjs
import { defineConfig } from 'astro/config'
export default defineConfig({
env: {
schema: {
// ...
}
}
})

然后你可以使用 envField 助手 将变量注册为字符串、数字、枚举或布尔值。通过为每个变量提供 context(客户端或服务器)和 access(机密或公共)来定义 环境变量类型,并在对象中传递任何其他属性,例如 optionaldefault

¥You can then register variables as a string, number, enum, or boolean using the envField helper. Define the kind of environment variable by providing a context (client or server) and access (secret or public) for each variable, and pass any additional properties such as optional or default in an object:

astro.config.mjs
import { defineConfig, envField } from 'astro/config'
export default defineConfig({
env: {
schema: {
API_URL: envField.string({ context: "client", access: "public", optional: true }),
PORT: envField.number({ context: "server", access: "public", default: 4321 }),
API_SECRET: envField.string({ context: "server", access: "secret" }),
}
}
})

运行 astro devastro build 时将为你生成类型,但你可以运行 astro sync 仅生成类型。

¥Types will be generated for you when running astro dev or astro build, but you can run astro sync to generate types only.

¥Use variables from your schema

从适当的 /client/server 模块导入并使用你定义的变量:

¥Import and use your defined variables from the appropriate /client or /server module:

---
import { API_URL } from "astro:env/client"
import { API_SECRET_TOKEN } from "astro:env/server"
const data = await fetch(`${API_URL}/users`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_SECRET_TOKEN}`
},
})
---
<script>
import { API_URL } from "astro:env/client"
fetch(`${API_URL}/ping`)
</script>

¥Variable types

有三种环境变量,由你架构中定义的 context(客户端或服务器)和 access(秘密或公共)设置的组合决定:

¥There are three kinds of environment variables, determined by the combination of context (client or server) and access (secret or public) settings defined in your schema:

  • 公共客户端变量:这些变量最终会出现在你的最终客户端和服务器包中,并且可以通过 astro:env/client 模块从客户端和服务器访问:

    import { API_URL } from "astro:env/client"
  • 公共服务器变量:这些变量最终会出现在你的最终服务器包中,并且可以通过 astro:env/server 模块在服务器上访问:

    import { PORT } from "astro:env/server"
  • 秘密服务器变量:这些变量不是最终打包包的一部分,可以通过 astro:env/server 模块在服务器上访问:

    import { API_SECRET } from "astro:env/server"

    默认情况下,机密仅在运行时进行验证。你可以通过 配置 validateSecrets: true 在启动时启用验证私有变量。

¥Data types

目前支持四种数据类型:字符串、数字、枚举和布尔值:

¥There are currently four data types supported: strings, numbers, enums, and booleans:

import { envField } from "astro/config"
envField.string({
// context & access
optional: true,
default: "foo",
})
envField.number({
// context & access
optional: true,
default: 15,
})
envField.boolean({
// context & access
optional: true,
default: true,
})
envField.enum({
// context & access
values: ['foo', 'bar', 'baz'],
optional: true,
default: 'baz',
})
For a complete list of validation fields, see the envField API reference.

¥Retrieving secrets dynamically

尽管定义了架构,你可能仍希望检索给定机密的原始值或检索架构中未定义的机密。在这种情况下,你可以使用从 astro:env/server 导出的 getSecret()

¥Despite defining your schema, you may want to retrieve the raw value of a given secret or to retrieve secrets not defined in your schema. In this case, you can use getSecret() exported from astro:env/server:

import {
FOO, // boolean
getSecret
} from 'astro:env/server'
getSecret('FOO') // string | undefined
Learn more in the API reference.

¥Limitations

  1. astro:env 是一个虚拟模块,这意味着它只能在 Astro 上下文中使用。例如,你可以在以下情况下使用它:

    • 中间件

    • Astro 路由和端点

    • Astro 组件

    • 框架组件

    • 模块

    你无法在以下情况下使用它,而必须求助于 process.env

    • astro.config.mjs

    • 脚本

  2. @astrojs/cloudflare 与其他适配器略有不同。环境变量的范围是请求,而 Node.js 则是全局的。

    这意味着你始终需要在请求范围内使用机密:

    src/middleware.ts
    import { defineMiddleware } from "astro:middleware"
    import { FOO, getSecret } from "astro:env"
    console.log(FOO) // undefined
    console.log(getSecret("FOO")) // undefined
    export const onRequest = defineMiddleware((context, next) => {
    console.log(FOO) // boolean
    console.log(getSecret("FOO")) // string
    return next()
    })
Astro 中文网 - 粤ICP备13048890号