环境变量

环境变量是一种存储配置值或敏感数据的方式,这些数据不应该直接包含在您的应用程序代码中。这些变量通常用于 API 密钥、数据库连接字符串或其他环境特定设置。

环境变量类型

构建时

  • PUBLIC_ 开头的环境变量,在 客户端服务器 上都可用。

服务器端

  • 仅在 服务器 上可访问的环境变量。

重要!不要 使用 构建时 环境变量(即以 PUBLIC_ 开头的变量)来存储任何敏感信息,例如 API 密钥、机密、密码等。这些变量在浏览器中是可访问的,仅限公共数据

.env.local
# This will only be available when run on the server
API_KEY=secretApiKeyHere
# This will be available everywhere
PUBLIC_API_URL=https://api.example.com

默认环境变量

QwikCity 默认包含一些环境变量

  • BASE_URL: string - 返回页面的基本 URL,
  • MODE: string - 返回渲染模式,
  • DEV: boolean - 返回是否处于开发模式,
  • PROD: boolean - 返回是否处于生产模式,
  • SSR: boolean - 返回是否使用 SSR 渲染

在 QwikCity 中访问环境变量的首选方法是通过 import.meta.env.*(客户端)或在服务器端运行时通过 Request 对象。

process.env 是 Node.js 专属 API,应尽量避免使用。

构建时变量

构建时变量由 Vite 提供支持。它们在 .env 文件中定义,并且在浏览器和服务器端代码中可用。

请注意,构建时变量应被视为公共,因为它们将被硬编码到浏览器构建中,任何人都可以轻松读取。

构建时变量默认以 PUBLIC_ 为前缀,可以使用 import.meta.env.PUBLIC_* 访问。

定义变量

.env.local
PUBLIC_API_URL=https://api.example.com

用法

src/routes/index.tsx
import { component$ } from '@builder.io/qwik';
 
export default component$(() => {
  // `import.meta.env.PUBLIC_*` variables can be read anywhere, including browser
  return <div>PUBLIC_API_URL: {import.meta.env.PUBLIC_API_URL}</div>
})

import.meta.env.PUBLIC_* 变量可以在任何地方读取,但不要在其中放置任何敏感信息,因为它们对客户端可见。

服务器端变量

服务器端变量本质上是运行时变量,仅在服务器端代码中可用。

它们在构建时未知,并且在浏览器中不可用,因此可以被视为私有

在生产环境中,设置服务器端变量非常依赖于平台。大多数平台允许您从其仪表板或 CLI 设置环境变量。有关更多信息,请参阅您的平台(cloudflare、vercel、netlify)文档。

Docker 和 Fastify 的特殊注意事项:

  • Docker:虽然 Docker 允许在 Dockerfile 中直接包含环境变量,但这可能会暴露敏感数据。更安全的做法是在运行时使用 Docker Compose 管理这些变量。例如
docker-compose.yml
version: '3.8'
services:
 your-service:
   image: your-image-name
   environment:
     - FOO=BAR
  • Docker 中的 Fastify:当使用 Fastify 时,放置在 .env.env.local 文件中的环境变量可能不会在生产环境中自动识别。为了使这些设置生效,可能需要在您的 Fastify 应用程序中显式加载它们,或者如上所示通过 Docker 的环境管理系统(Docker Compose)传递它们。

定义变量

.env.local
DB_PRIVATE_KEY=123456789

确保您永远不要将 .env.local 文件提交到 git。

用法示例

服务器端变量只能在暴露 RequestEvent 对象的服务器端 API 中访问,例如 routeLoader$()routeAction$()server$() 和端点处理程序,例如 onGetonPostonRequest 等。

src/routes/index.tsx
import {
  routeLoader$,
  routeAction$,
  server$,
  type RequestEvent,
} from '@builder.io/qwik-city';
 
export const onGet = (requestEvent: RequestEvent) => {
  console.log(requestEvent.env.get('DB_PRIVATE_KEY'));
};
 
export const onPost = (requestEvent: RequestEvent) => {
  console.log(requestEvent.env.get('DB_PRIVATE_KEY'));
};
 
export const useAction = routeAction$(async (_, requestEvent) => {
  console.log(requestEvent.env.get('DB_PRIVATE_KEY'));
});
 
export const useLoader = routeLoader$(async (requestEvent) => {
  console.log(requestEvent.env.get('DB_PRIVATE_KEY'));
});
 
export const serverFunction = server$(function () {
  // `this` is the `RequestEvent` object
  console.log(this.env.get('DB_PRIVATE_KEY'));
});

在服务器端渲染架构中的用法(示例:Express)

为了在服务器端渲染架构中访问 .env 变量,您需要使用单例设计模式,在插件中初始化数据库,并在需要的地方使用 getDB 访问它。

src/util/db.ts
let _db!: AppDatabase;
 
export function getDB() {
  // eslint-disable-next-line
  if (!_db) {
    throw new Error('DB not set');
  }
  return _db;
}
 
export async function initializeDbIfNeeded(factory: () => Promise<AppDatabase>) {
  // eslint-disable-next-line
  if (!_db) {
    _db = await factory();
  }
}
export const onRequest: RequestHandler = async ({ env }) => {
  const url = env.get('PRIVATE_LIBSQL_DB_URL')!;
  const authToken = env.get('PRIVATE_LIBSQL_DB_API_TOKEN')!;
  await initializeDbIfNeeded(initLibSql(url, authToken));
};

在整个应用程序生命周期中管理环境变量

在现代应用程序中,环境变量在管理各种环境中的应用程序设置和配置方面起着至关重要的作用,而无需将敏感数据硬编码到源代码中。

Qwik City 适配器使用以下方法

  • Azure、Cloud Run、Netlify Edge、Node Server 使用 ORIGIN 或 URL
  • Cloudflare Pages 使用 CF_PAGES_URL 或 ORIGIN
  • Vercel 使用 VERCEL_URL

注意:这不是关于环境变量的全面指南,也不涵盖所有第三方托管场景。它旨在提供可应用于各种环境的见解。

观看此视频以获取详细说明:https://youtu.be/NPf39RWc8LM

贡献者

感谢所有帮助改进此文档的贡献者!

  • manucorporat
  • the-r3aper7
  • mrhoodz
  • wtlin1228
  • RumNCodeDev
  • Jemsco