使用环境变量
Astro 让你能够访问 Vite 的内置环境变量支持,并包含一些为你的项目提供的默认环境变量,允许你访问当前项目的配置值(例如 site
、base
)、判断项目是在开发环境还是生产环境中运行,等等。
Astro 还提供了一种以类型安全的方式使用和组织环境变量的方法。它可以在 Astro 上下文(例如 Astro 组件、路由和端点、UI 框架组件、中间件)中使用,并通过 Astro 配置中的模式(schema)进行管理。
Vite 的内置支持
标题为“Vite 的内置支持”的部分Astro 使用 Vite 对环境变量的内置支持,这些变量在构建时会被静态替换,并允许你使用其任何方法来处理它们。
请注意,虽然所有环境变量都可以在服务器端代码中使用,但出于安全考虑,只有以 PUBLIC_
为前缀的环境变量才可以在客户端代码中使用。
SECRET_PASSWORD=password123PUBLIC_ANYBODY=there
在这个例子中,PUBLIC_ANYBODY
(通过 import.meta.env.PUBLIC_ANYBODY
访问)将在服务器或客户端代码中可用,而 SECRET_PASSWORD
(通过 import.meta.env.SECRET_PASSWORD
访问)将只在服务器端可用。
.env
文件不会在配置文件内加载。
TypeScript 的智能提示
标题为“TypeScript 的智能提示”的部分默认情况下,Astro 在 astro/client.d.ts
中为 import.meta.env
提供了类型定义。
虽然你可以在 .env.[mode]
文件中定义更多自定义环境变量,但你可能希望为以 PUBLIC_
为前缀的用户定义环境变量获取 TypeScript 智能提示(IntelliSense)。
要实现这一点,你可以在 src/
目录下创建一个 env.d.ts
文件,并像这样配置 ImportMetaEnv
interface ImportMetaEnv { readonly DB_PASSWORD: string; readonly PUBLIC_POKEAPI: string; // more env variables...}
interface ImportMeta { readonly env: ImportMetaEnv;}
默认环境变量
标题为“默认环境变量”的部分Astro 开箱即用地包含了一些环境变量
import.meta.env.MODE
: 网站运行的模式。在运行astro dev
时为development
,在运行astro build
时为production
。import.meta.env.PROD
: 如果你的网站在生产环境中运行,则为true
;否则为false
。import.meta.env.DEV
: 如果你的网站在开发环境中运行,则为true
;否则为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
配置选项,则为 Astro 生成的资源链接的前缀。这可以用来创建 Astro 未处理的资源链接。
像使用其他任何环境变量一样使用它们。
const isProd = import.meta.env.PROD;const isDev = import.meta.env.DEV;
设置环境变量
标题为“设置环境变量”的部分.env
文件
标题为“.env 文件”的部分环境变量可以从项目目录中的 .env
文件加载。
只需在项目目录中创建一个 .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
)。这允许你在不同时间使用不同的环境变量集。
astro dev
和 astro build
命令分别默认为 "development"
和 "production"
模式。你可以使用 --mode
标志运行这些命令,为 mode
传递不同的值并加载匹配的 .env
文件。
这使你能够运行开发服务器或构建连接到不同 API 的网站
# Run the dev server connected to a "staging" APInpm run astro dev -- --mode staging
# Build a site that connects to a "production" API with additional debug informationnpm run astro build -- --devOutput
# Build a site that connects to a "testing" APInpm run astro build -- --mode testing
# Run the dev server connected to a "staging" APIpnpm astro dev --mode staging
# Build a site that connects to a "production" API with additional debug informationpnpm astro build --devOutput
# Build a site that connects to a "testing" APIpnpm astro build --mode testing
# Run the dev server connected to a "staging" APIyarn astro dev --mode staging
# Build a site that connects to a "production" API with additional debug informationyarn astro build --devOutput
# Build a site that connects to a "testing" APIyarn astro build --mode testing
关于 .env
文件的更多信息,请参阅 Vite 文档。
在 Astro 配置文件中
标题为“在 Astro 配置文件中”的部分Astro 在加载其他文件之前会先评估配置文件。这意味着你不能在 astro.config.mjs
中使用 import.meta.env
来访问在 .env
文件中设置的环境变量。
你可以在配置文件中使用 process.env
来访问其他环境变量,例如由 CLI 设置的变量。
你也可以使用 Vite 的 loadEnv
辅助函数来手动加载 .env
文件。
import { loadEnv } from "vite";
const { SECRET_PASSWORD } = loadEnv(process.env.NODE_ENV, process.cwd(), "");
pnpm
不允许你导入未直接安装在项目中的模块。如果你正在使用 pnpm
,你需要安装 vite
才能使用 loadEnv
辅助函数。
pnpm add -D vite
使用 CLI
标题为“使用 CLI”的部分你也可以在运行项目时添加环境变量
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 npm run dev
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 pnpm run dev
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 yarn run dev
获取环境变量
标题为“获取环境变量”的部分在 Astro 中,环境变量通过 import.meta.env
访问,使用的是 ES2020 中添加的 import.meta
特性,而不是 process.env
。
例如,使用 import.meta.env.PUBLIC_POKEAPI
来获取 PUBLIC_POKEAPI
环境变量。
// When import.meta.env.SSR === trueconst data = await db(import.meta.env.DB_PASSWORD);
// When import.meta.env.SSR === falseconst data = fetch(`${import.meta.env.PUBLIC_POKEAPI}/pokemon/squirtle`);
使用 SSR 时,可以根据所使用的 SSR 适配器在运行时访问环境变量。对于大多数适配器,你可以使用 process.env
访问环境变量,但有些适配器的工作方式不同。对于 Deno 适配器,你将使用 Deno.env.get()
。请参阅如何访问 Cloudflare 运行时来在使用 Cloudflare 适配器时处理环境变量。Astro 会首先检查服务器环境中的变量,如果不存在,Astro 会在 .env
文件中查找它们。
类型安全的环境变量
标题为“类型安全的环境变量”的部分astro:env
API 允许你为已设置的环境变量配置一个类型安全的模式。这允许你指定它们应该在服务器端还是客户端可用,并定义它们的数据类型和附加属性。
astro:env
兼容。
基本用法
标题为“基本用法”的部分定义你的模式
标题为“定义你的模式”的部分要配置模式,请将 env.schema
选项添加到你的 Astro 配置中
import { defineConfig } from "astro/config";
export default defineConfig({ env: { schema: { // ... } }})
然后,你可以使用 envField
辅助函数将变量注册为字符串、数字、枚举或布尔值。通过为每个变量提供 context
("client"
或 "server"
)和 access
("secret"
或 "public"
)来定义环境变量的类型,并在一个对象中传递任何附加属性,如 optional
或 default
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 dev
或 astro build
时,将会为你生成类型,但你也可以运行 astro sync
来仅生成类型。
使用你模式中的变量
标题为“使用你模式中的变量”的部分从相应的 /client
或 /server
模块中导入并使用你定义的变量
---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>
变量类型
标题为“变量类型”的部分环境变量共有三种类型,由你在模式中定义的 context
("client"
或 "server"
)和 access
("secret"
或 "public"
)设置的组合决定
-
公共客户端变量:这些变量最终会包含在你的客户端和服务器端构建包中,可以通过
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
来在启动时验证私有变量。
不支持秘密客户端变量,因为没有安全的方法将此数据发送到客户端。因此,无法在你的模式中同时配置 context: "client"
和 access: "secret"
。
数据类型
标题为“数据类型”的部分目前支持四种数据类型:字符串、数字、枚举和布尔值
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",})
envField
API 参考。
动态检索密钥
标题为“动态检索密钥”的部分尽管定义了模式,你可能仍希望检索给定密钥的原始值或检索未在模式中定义的密钥。在这种情况下,你可以使用从 astro:env/server
导出的 getSecret()
import { FOO, // boolean getSecret} from "astro:env/server";
getSecret("FOO"); // string | undefined
astro:env
是一个虚拟模块,这意味着它只能在 Astro 上下文中使用。例如,你可以在以下地方使用它
- 中间件
- Astro 路由和端点
- Astro 组件
- 框架组件
- 模块
你不能在以下地方使用它,而必须使用 process.env
astro.config.mjs
- 脚本