Переменные окружения

Приложения Qwik могут читать переменные окружения двумя основными способами: переменные времени сборки и переменные на стороне сервера.

process.env - это API только для Node.js, и его следует избегать любой ценой.

Переменные времени сборки

Переменные времени сборки работают через Vite. Они определяются в файлах .env и доступны в браузере и в коде на стороне сервера.

** ВАЖНО! НЕ** используйте import.meta.env.PUBLIC_* для хранения конфиденциальной информации, такой как ключи API, секреты, пароли и т.д. Только общедоступные данные.

Обратите внимание, что переменные времени сборки следует рассматривать как публичные, поскольку они будут жестко закодированы в сборке для браузера, и могут быть легко прочитаны кем угодно.

Переменные времени сборки по умолчанию имеют префикс PUBLIC_ и могут быть доступны с помощью import.meta.env.PUBLIC_*.

.env
VITE_API_URL=https://api.example.com
src/routes/index.tsx
import { component$ } from '@builder.io/qwik';
 
export default component$(() => {
  // переменные `import.meta.env.PUBLIC_*` могут быть прочитаны где угодно, включая браузер
  return <div>PUBLIC_API_URL: {import.meta.env.VITE_API_URL}</div>
})

переменные import.meta.env.PUBLIC_* можно читать где угодно, но не помещайте в них конфиденциальную информацию, так как она будет видна клиенту.

Переменные окружения на стороне сервера

Переменные окружения на стороне сервера - это, по сути, переменные времени выполнения, которые доступны только в коде на стороне сервера.

Они не определены во время сборки и недоступны в браузере, поэтому их можно считать приватными.

Доступ к таким переменным на стороне сервера возможен только в API, которые используют объект RequestEvent, например, routeLoader$(), routeAction$(), server$() и обработчики конечных точек, такие как onGet, onPost, onRequest и т.д.

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` - объект `RequestEvent`.
  console.log(this.env.get('DB_PRIVATE_KEY'));
});

Определение переменных на стороне сервера

Во время разработки переменные на стороне сервера могут быть определены в файле .env.local, этот файл по умолчанию игнорируется git'ом, поэтому безопасно помещать в него конфиденциальную информацию.

.env.local
DB_PRIVATE_KEY=123456789

Убедитесь, что вы никогда не коммитите в git файлы .env.local.

В производственной среде установка переменных на стороне сервера зависит от конкретной платформы. Большинство платформ позволяют устанавливать переменные окружения из своей панели управления или CLI. Пожалуйста, обратитесь к документации по вашей платформе (cloudflare, vercel, netlify) для получения дополнительной информации.

Доступ к переменным окружения в архитектуре serverfull (пример: Express)

Для доступа к переменным .env в архитектуре serverfull нам нужно использовать паттерн проектирования singleton, инициализировать базу данных в плагине и обращаться к ней с помощью 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();
  }
}
src/routes/plugin@db.ts
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));
};

Участники

Спасибо всем участникам, которые помогли сделать эту документацию лучше!

  • manucorporat
  • the-r3aper7
  • mrhoodz
  • wtlin1228