← Назад к вопросам
Как приложение достигает Base URL из Env файла?
1.7 Middle🔥 123 комментариев
#JavaScript Core
Комментарии (3)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как приложение достигает Base URL из Env файла
Окружение (Environment Variables) - это способ сохранять конфигурацию отдельно от кода. Base URL API - классический пример такой конфигурации, так как разные окружения (dev, staging, production) имеют разные адреса.
1. Что такое Environment Variables
Env файлы - это простые текстовые файлы с парами ключ-значение:
# .env.local (локальное развитие)
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
DATABASE_URL=postgresql://localhost/myapp
API_SECRET_KEY=secret123
# .env.staging
NEXT_PUBLIC_API_BASE_URL=https://staging-api.example.com
# .env.production
NEXT_PUBLIC_API_BASE_URL=https://api.example.com
Важно: Переменные с префиксом NEXT_PUBLIC_ доступны в браузере (публичные), остальные только на сервере.
2. Как Next.js загружает env файлы
Next.js автоматически загружает переменные по приоритету:
.env.{NODE_ENV}.local
.env.{NODE_ENV}
.env.local
.env
Примеры:
# Если NODE_ENV=development
# Загружает в порядке:
# 1. .env.development.local (если существует)
# 2. .env.development
# 3. .env.local
# 4. .env
# Если NODE_ENV=production
# Загружает в порядке:
# 1. .env.production.local
# 2. .env.production
# 3. .env.local
# 4. .env
3. Использование в Next.js приложении
На клиентской стороне (браузер)
// lib/api.ts
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000';
export const api = {
async get(endpoint: string) {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
method: 'GET'
});
return response.json();
},
async post(endpoint: string, data: unknown) {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
return response.json();
}
};
// Использование
await api.get('/api/v1/questions');
// Полный URL: http://localhost:8000/api/v1/questions (в dev)
// Полный URL: https://api.example.com/api/v1/questions (в production)
На серверной стороне (Node.js)
// app/api/route.ts - API route в Next.js
const BACKEND_API_URL = process.env.NEXT_PUBLIC_API_BASE_URL;
const API_SECRET = process.env.API_SECRET_KEY; // Только на сервере
export async function GET(request: Request) {
const response = await fetch(`${BACKEND_API_URL}/api/v1/questions`, {
headers: {
'Authorization': `Bearer ${API_SECRET}`,
'Content-Type': 'application/json'
}
});
const data = await response.json();
return Response.json(data);
}
4. Структура env файлов в проекте
project/
├── .env # Общие для всех (в git)
├── .env.local # Локальные переопределения (НЕ в git)
├── .env.development # Dev окружение (в git)
├── .env.development.local # Dev переопределения (НЕ в git)
├── .env.staging # Staging окружение (в git)
├── .env.production # Production (в git)
└── .gitignore
.gitignore должен содержать:
# .gitignore
.env.local
.env.*.local
.env
Так сохраняется безопасность - локальные секреты не коммитятся.
5. Полный пример конфигурации
.env (базовые значения)
NEXT_PUBLIC_APP_NAME=PrepBro
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
NEXT_PUBLIC_LOG_LEVEL=debug
.env.local (локальные переопределения)
# Разработчик юзает свой local server
NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:3001
DEVELOPER_NAME=John
.env.production (production конфиг)
NEXT_PUBLIC_API_BASE_URL=https://api.prepbro.ru
NEXT_PUBLIC_LOG_LEVEL=error
API_ENCRYPTION_KEY=very-secret-key
6. Работа с типами (TypeScript)
// lib/config.ts
export const config = {
api: {
baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL || '',
timeout: 30000
},
app: {
name: process.env.NEXT_PUBLIC_APP_NAME || 'PrepBro',
version: process.env.NEXT_PUBLIC_APP_VERSION || '1.0.0'
},
secret: {
// Только на сервере
dbUrl: process.env.DATABASE_URL,
apiKey: process.env.API_SECRET_KEY
}
} as const;
// Со строгой типизацией
type Config = typeof config;
export const getConfig = (): Config => config;
// Использование
import { config } from '@/lib/config';
const apiUrl = config.api.baseUrl;
7. Валидация env на старте
// lib/env.ts
function validateEnv() {
const required = [
'NEXT_PUBLIC_API_BASE_URL',
'DATABASE_URL',
'API_SECRET_KEY'
];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) {
throw new Error(
`Missing required environment variables: ${missing.join(', ')}`
);
}
}
// В entry point приложения
if (typeof window === 'undefined') {
// Только на сервере
validateEnv();
}
8. Доступ во время разработки
npm run dev
# Terminal
$ npm run dev
# Next.js автоматически:
# 1. Загружает .env.local
# 2. Загружает .env.development
# 3. Загружает .env
# 4. Объединяет их (local имеет приоритет)
npm run build
# Terminal
$ npm run build
# Загружает .env.production.local, .env.production, .env
# Встраивает значения NEXT_PUBLIC_* прямо в JavaScript бандл
Доступ в коде
// lib/api.ts
const API_URL = process.env.NEXT_PUBLIC_API_BASE_URL;
console.log(API_URL); // http://localhost:8000 (в dev)
9. Условная загрузка конфиков
// lib/config.ts
const isDev = process.env.NODE_ENV === 'development';
const isProduction = process.env.NODE_ENV === 'production';
export const config = {
api: {
baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL,
// В dev можно включить логирование
logRequests: isDev,
// В production отключить retry
retryCount: isProduction ? 0 : 3
}
};
10. Переменные во время сборки (Build time)
Для Next.js переменные встраиваются при сборке:
// components/Status.tsx
export function Status() {
// Это значение встроится ПРЯМО в JavaScript при сборке
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL;
// Эквивалентно:
// const apiUrl = 'https://api.example.com'; // после сборки
return <div>API: {apiUrl}</div>;
}
11. Переменные во время выполнения (Runtime)
Для значений, которые меняются после сборки - используем API:
// app/api/config/route.ts
export async function GET() {
// Это выполняется при КАЖДОМ запросе
return Response.json({
apiUrl: process.env.NEXT_PUBLIC_API_BASE_URL,
timestamp: new Date().toISOString()
});
}
// На клиенте
const { apiUrl, timestamp } = await fetch('/api/config').then(r => r.json());
12. Безопасность
Что НЕЛЬЗЯ в NEXT_PUBLIC_*
# ПЛОХО - видно в браузере
NEXT_PUBLIC_API_SECRET=secret123
NEXT_PUBLIC_DB_PASSWORD=password
Правильно
# .env.local (НЕ в git)
API_SECRET=secret123
DB_PASSWORD=password
# .env (в git, публичные значения)
NEXT_PUBLIC_API_BASE_URL=https://api.example.com
NEXT_PUBLIC_APP_VERSION=1.0.0
13. Пример полного потока
# 1. Разработчик клонирует репозиторий
git clone ...
cd project
# 2. Создает .env.local для своей машины
echo "NEXT_PUBLIC_API_BASE_URL=http://localhost:8000" > .env.local
# 3. Запускает приложение
npm run dev
# 4. В браузере открывается http://localhost:3000
# Приложение автоматически юзает http://localhost:8000 как API_BASE_URL
# 5. На production (Dokku, Vercel и т.д.)
# Задают переменные через:
# - Dokku: dokku config:set myapp NEXT_PUBLIC_API_BASE_URL=https://api.prod.com
# - GitHub Actions: secrets
# - .env файл на сервере
Итого
- Env файлы хранят конфигурацию отдельно от кода
- NEXT_PUBLIC_* видны в браузере, остальные только на сервере
- Приоритет: .local > .{NODE_ENV} > .env
- Типизируй конфиг для безопасности
- Валидируй обязательные переменные на старте
- Никогда не коммитай .env.local с секретами