SHIN
Node.js 실전 팁 20선
20편환경 변수는 비밀 키, DB 연결 정보, 기능 플래그 등을 코드에서 분리하는 핵심 방법입니다.
npm install dotenv# .env (절대 git에 커밋하지 않음!)
DATABASE_URL=sqlite:./dev.db
JWT_SECRET=super-secret-key-change-in-production
PORT=3000
NODE_ENV=development// 앱 진입점 최상단에서 한 번만 호출
import 'dotenv/config';
// 또는
require('dotenv').config();
console.log(process.env.PORT); // '3000'# dotenv 없이도 됩니다
node --env-file=.env app.js
node --env-file=.env --env-file=.env.local app.js// config/env.ts
import { z } from 'zod';
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']),
PORT: z.coerce.number().int().min(1).max(65535).default(3000),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32, 'JWT_SECRET은 최소 32자여야 합니다'),
API_KEY: z.string().optional(),
});
export type Env = z.infer<typeof envSchema>;
const parsed = envSchema.safeParse(process.env);
if (!parsed.success) {
console.error('환경 변수 오류:', parsed.error.format());
process.exit(1);
}
export const env = parsed.data;.env # 기본값 (git 커밋 가능, 비밀 없음)
.env.local # 로컬 오버라이드 (git 제외)
.env.development # 개발 환경
.env.production # 프로덕션 환경
.env.test # 테스트 환경// 환경별 파일 로드
const env = process.env.NODE_ENV || 'development';
dotenv.config({ path: '.env' });
dotenv.config({ path: `.env.${env}`, override: true });
dotenv.config({ path: '.env.local', override: true });# 비밀 환경 변수 파일 제외
.env.local
.env.*.local
.env.production// 검증된 env 객체만 사용
import { env } from '@/config/env';
const server = app.listen(env.PORT, () => {
console.log(`서버 실행 중: http://localhost:${env.PORT}`);
});
// process.env.PORT 직접 접근 대신 env.PORT 사용보안 규칙: 환경 변수는 절대 로그에 출력하지 말고, 비밀 파일은 항상 .gitignore에 추가하세요.