Astro + Cloudflare worker 环境变量问题
- Astro
- Cloudflare worker
- 04 Feb, 2026
我使用的是Astro框架 + Cloudflare worker 部署,AI 给我写的代码里面充满了locals?.runtime?.env , import.meta.env ,process.env 等环境变量,通过各种测验和自己的理解,还有 AI 给的回复,整理如下:
Q:wrangler dev 和 wrangler dev —remote 有什么区别
简短区别:
-
wrangler dev
默认本地模式(Miniflare 模拟)。快、可离线、热更新快,但有些行为和线上不完全一致(比如缓存、WebSocket、部分绑定特性、运行时差异等)。 -
wrangler dev --remote
远程模式,代码上传到 Cloudflare 边缘运行(dev 部署)。行为更接近线上、能用真实的 KV/D1/R2 等,但速度慢一些,需要联网和登录,改动会上传。
你现在的问题如果和环境变量/运行时有关,--remote 更能反映真实环境。
Q:locals?.runtime?.env 是什么? import.meta.env 是什么 ? process.env 是什么?
下面用 Astro + Wrangler 的上下文解释:
1. locals?.runtime?.env 是什么
- 这是 Astro Cloudflare 适配器在请求处理时注入的运行时环境变量集合。
- 只在 Cloudflare Worker 运行时有值(包括
wrangler dev的 worker 模式)。 - 它来自 Worker 的
env(也就是你在wrangler.jsonc的vars、D1/KV/R2 绑定等)。 - 只能在请求链路里拿到(
middleware/API/page的context.locals)。
2. import.meta.env 是什么
- Vite/Astro 在构建时注入的环境变量。
- 在 服务端/SSR 代码里,构建时是可以把非 PUBLIC_ 的环境变量编进去的(取决于构建时环境)。
- 会包含你允许暴露给客户端或构建的变量(在 Astro 里默认是 PUBLIC_ 前缀)。
3. process.env 是什么
- Node.js 进程环境变量(本地开发时常见)。
- Cloudflare Worker 运行时没有
process,所以线上/remote 模式基本不可用。 - 本地
astro dev可以用,但wrangler dev的 worker 运行时通常没有。
一句话总结:
- 线上/
wrangler dev:主要靠locals.runtime.env - 本地 Node 模式:可以用
process.env - 构建/客户端:只能用
import.meta.env
到最后其实我还是有些糊涂,我有让AI写了一个公共函数,我不用关心到底应该写哪个 env,统一走 getEnv()函数
type EnvRecord = Record<string, string | undefined>;
type RuntimeEnvRecord = Record<string, unknown> | undefined;
let runtimeEnv: RuntimeEnvRecord = undefined;
export function setRuntimeEnv(env: RuntimeEnvRecord) {
runtimeEnv = env;
}
function getImportMetaEnv(): EnvRecord | undefined {
try {
return (import.meta.env ?? {}) as EnvRecord;
} catch {
return undefined;
}
}
export function getEnv(key: string): string | undefined {
const runtimeValue = runtimeEnv?.[key];
if (typeof runtimeValue === 'string') {
return runtimeValue;
}
const metaEnv = getImportMetaEnv();
if (metaEnv) {
const value = metaEnv[key];
if (value !== undefined) {
return value;
}
}
if (typeof process !== 'undefined' && process.env) {
return process.env[key];
}
return undefined;
}
export function getEnvBoolean(key: string, defaultValue: boolean): boolean {
const raw = getEnv(key);
if (raw === undefined) {
return defaultValue;
}
return raw === 'true' || raw === '1';
}
不过需要在 middleware.ts 中增加一段代码:
if (locals?.runtime?.env) {
setRuntimeEnv(locals.runtime.env as Record<string, unknown>);
}