blog

Vite에서 development·production 환경 변수 분리하기

Front-end / Tooling#Vite#환경 변수#axios#HTTPS

1. env 파일 분리

Vite는 실행 모드에 맞는 파일을 자동으로 읽는다. vite(dev)는 development, vite build는 production 모드다.

# .env - 모든 모드 공통
VITE_APP_NAME=my-app

# .env.development - 개발 모드
VITE_API_BASE_URL=http://localhost:8080

# .env.production - 운영 빌드
VITE_API_BASE_URL=https://api.example.com

같은 키가 있으면 모드별 파일이 .env보다 우선한다. 개인 설정은 .env.local, .env.development.local에 두고 *.local만 gitignore하는 것이 Vite의 기본 관례다.

VITE_ 접두사가 붙은 변수는 빌드 결과물(JS 번들)에 그대로 들어가 누구나 볼 수 있다. gitignore를 해도 비밀이 되지 않으므로 API 키 같은 비밀값은 프론트엔드 env에 두지 않는다.

2. API baseURL

프로토콜까지 포함한 전체 URL을 env에 두면 분기 코드가 필요 없다.

// src/apis/instance.ts
import axios from 'axios';

export const instance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
});

3. 개발 서버를 HTTPS로 띄우기

vite.config.ts의 server.https는 개발 서버(vite)에만 적용된다. 운영 환경의 HTTPS는 빌드 결과물을 제공하는 웹 서버(nginx, CDN 등)에서 설정한다.

// vite.config.ts
import fs from 'node:fs';
import path from 'node:path';
import { defineConfig, loadEnv } from 'vite';

export default defineConfig(({ mode }) => {
  // config 파일 안에서는 import.meta.env를 쓸 수 없어 loadEnv로 읽음
  const env = loadEnv(mode, process.cwd());

  return {
    server: {
      host: '0.0.0.0', // 같은 네트워크의 모바일 기기에서 접속 가능
      https:
        env.VITE_USE_HTTPS === 'true'
          ? {
              key: fs.readFileSync(path.resolve(__dirname, 'localhost-key.pem')),
              cert: fs.readFileSync(path.resolve(__dirname, 'localhost.pem')),
            }
          : undefined,
    },
  };
});

인증서 파일은 mkcert localhost 192.168.x.x처럼 발급하고 저장소에는 커밋하지 않는다.