기존에는 vue.config.js 에서 CommonJS 방식으로 설정을 배웠고 해왔다.
vite
를 사용해보고자 사용하는데 ESmodule 방식으로 설정을 하는데 좀 어려웠다
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
})
여기에서 나는 resolve alias
를 설정하고 server proxy
를 환경벌로 설정하고 싶었다.
우선 환경별로 설정하기전 dotenv
라이브러리를 설치한다.
VITE 환경변수 - 공식문서 일부
.env 파일들
Vite는 dotenv를 이용해 환경 변수가 저장된 디렉터리 내 아래의 파일에서 환경 변수를 가져옵니다.
.env # 모든 상황에서 사용될 환경 변수
.env.local # 모든 상황에서 사용되나, 로컬 개발 환경에서만 사용될(Git에 의해 무시될) 환경 변수
.env.[mode] # 특정 모드에서만 사용될 환경 변수
.env.[mode].local # 특정 모드에서만 사용되나, 로컬 개발 환경에서만 사용될(Git에 의해 무시될) 환경 변수
npm i dotenv
루트 디렉토리에 $ .env.[환경명]
ex ) .env.dev
, .env.prd
을 생성한다.
VITE_APP_ENVIRONMENT=DEV
VITE_APP_SERVER=https://abc.com
ex ) VITE_APP_ENVIRONMENT=DEV
ex ) npm run 실행명(start-dev, dev)
그리고 "vite --mode
dev
" 를 적어준다.
local일 경우 --mode local 은 viet에서 .local
접미사를 가진 환경 파일을 특별하게 처리를 한다고 한다.
⚠️ error when starting dev server: Error: "local" cannot be used as a mode name because it conflicts with the .local postfix for .env files. at loadEnv
Vite는 .env.[mode]
형식의 파일을 로드할 때, .env.local
파일을 항상 특별히 처리한다고 한다. local을 모드 이름으로 지정하면 .local
접미사와 충돌하여 이와 같은 에러가 발생한다.
음 .. 웬만하면 local 보다는 다른명으로 하는게 낫겠다.
"scripts": {
"start-dev": "vite --mode dev",
"start-local": "vite --mode 🔴mylocal 또는 test 등등",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
})
위 기본세팅에서 이제 설정한 환경파일과 환경변수를 server proxy 설정을 한다.
package.json 에서 --mode 를 설정했었다.
해당 모드를 동적으로 defineConfig에서 설정하기 위해 매개변수를 받아오는 코드로 바꾼다.
// 변경전
export default defineConfig({
plugins: [react()],
})
// 변경후
export default defineConfig(({ mode }) => {
return {
plugins: [react()]
}
})
Vite는 해당 모드를 defineConfig 함수의 매개변수로 전달한다. 이를 통해 Vite 설정 파일에서 모드에 따라 다른 설정을 적용할 수 있다.
package.json
에서 설정한 --mode dev
매개변수로 mode를 전달받는 형태로 만들어 준다.export default defineConfig(({ mode }) => {
🟢const envPath = path.resolve(new URL(import.meta.url).pathname, `.env.${mode}`)
•••••
return {
•••••
•••••
}
•••••
})
envPath
변수를 생성한다. defineConfig
에서 전달받은 매개변수 mode
를 동적으로 받아 루트디렉토리에 있는 환경파일들의 파일경로를 담는다.
export default defineConfig(({ mode }) => {
const envPath = path.resolve(new URL(import.meta.url).pathname, `.env.${mode}`)
🟢dotenv.config({ path: envPath })
•••••
return {
•••••
•••••
}
•••••
})
dotenv
패키지를 사용하여 지정된 경로에 있는 환경 변수 파일을 로드하는 기능을 한다. 이 코드를 통해 환경 변수 파일에 정의된 변수들을 process.env에 설정할 수 있다.
import { defineConfig, 🟢loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
const envPath = path.resolve(new URL(import.meta.url).pathname, `.env.${mode}`)
dotenv.config({ path: envPath })
🟢const env = loadEnv(mode, process.cwd(), '')
•••••
return {
•••••
•••••
}
•••••
})
loadEnv 함수
function loadEnv(
mode: string,
envDir: string,
prefixes: string | string[] = 'VITE_',
): Record<string, string>
관련: .env파일
Vite에서는 envDir(환경 파일 디렉터리)
안에 있는 .env
파일들을 로드한다. 이 때, 기본적으로 VITE_
로 시작하는 환경 변수만 로드된다.
⚠️ 단, 이 동작은 설정에서 prefixes 값을 변경하면 수정할 수 있다.
Vite는 envDir 디렉터리(기본값: 프로젝트 루트)에 있는 .env 파일들을 읽는다.
환경 변수 이름이 VITE_로 시작해야 Vite가 이를 인식하고 사용할 수 있다.
🟢사용가능
VITE_API_URL=https://example.com
VITE_APP_NAME=MyApp
위 변수들은 Vite에서 사용할 수 있다.
🔴다른 접두사 사용
prefixes 설정을 수정하면 VITE_ 외의 접두사도 사용할 수 있다.
import { defineConfig } from 'vite';
export default defineConfig({
envPrefix: ['VITE_', 'APP_']
});
이렇게 하면 APP_으로 시작하는 변수도 로드된다.
ex ) APP_SECRET_KEY=abcdef12345
loadEnv 함수 코드
📂 node_modules > vite > dist > node > index.d.ts
declare function loadEnv(mode: string, envDir: string, prefixes?: string | string[]): Record<string, string>;
1️⃣ mode
: Vite가 실행되는 모드를 나타내는 문자열이다. 실행환경 ex ) dev,
prod 등이 될 수 있다.
2️⃣ envDir
: 환경 변수 파일이 위치한 디렉토리의 경로이다. 일반적으로 process.cwd()를 사용하여 현재 작업 디렉토리를 지정한다.
ex ) C:\Users\...\...\...\vite.config.ts\.env.dev
3️⃣ prefixes
: 로드할 환경 변수의 접두사를 지정하는 문자열 또는 문자열 배열다. 빈 문자열('')을 사용하면 모든 환경 변수를 로드한다.
💡 빈 문자일 경우 모든 환경 변수를 로드한다
{ VITE_APP_ENVIRONMENT: 'DEV', VITE_APP_SERVER: 'https://abc.abc.com', ALLUSERSPROFILE: 'C:\\ProgramData', APPDATA: 'C:\\Users\\AppData\\Roaming', CHROME_CRASHPAD_PIPE_NAME: '\\\\.\\pipe\\crashpad_5276_XOTRGHZMDFBHYJKD', COLOR: '1', COLORTERM: 'truecolor', CommonProgramFiles: 'C:\\Program Files\\Common Files', 'CommonProgramFiles(x86)': 'C:\\Program Files (x86)\\Common Files', }
🕵️ 그래서 환경 변수명만 불러오고 싶을 땐
const env = loadEnv(mode, process.cwd(), 'VITE_')
세번째 인자에 'VITE_' 를 넣어준다.
{ VITE_APP_ENVIRONMENT: 'DEV', VITE_APP_SERVER: 'https://abc.abc.com' }
export default defineConfig(({ mode }) => {
const envPath = path.resolve(new URL(import.meta.url).pathname, `.env.${mode}`)
dotenv.config({ path: envPath })
const env = loadEnv(mode, process.cwd(), 'VITE_')
•••••
return {
•••••
🟢server: {
proxy: {
'/api': {
target: env.VITE_APP_SERVER,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
•••••
}
•••••
})
1️⃣ target : 프록시 요청을 보낼 대상 서버의 URL을 지정한다.
ex ) target: env.VITE_APP_SERVER
는 프록시 요청을 env.VITE_APP_SERVER
에 지정된 서버로 보낸다.
사용 : 클라이언트 코드에서 /api
로 시작하는 요청을 프록시 서버를 통해 실제 API 서버로 전달할 때 사용한다.
2️⃣ changeOrigin : 프록시 요청을 보낼 때 원본 요청의 호스트 헤더를 대상 서버의 호스트 헤더로 변경할지 여부를 지정한다.
ex ) changeOrigin: true
는 원본 요청의 호스트 헤더를 대상 서버의 호스트 헤더로 변경한다.
사용 : 대상 서버가 호스트 헤더를 기반으로 요청을 처리하는 경우 유용하다.
3️⃣ rewrite : 프록시 요청의 경로를 재작성하는 함수다. 경로를 변경하여 대상 서버에 전달할 수 있다.
ex ) rewrite: (path) => path.replace(/^\/api/, '')
는 /api로 시작하는 경로를 빈 문자열로 대체하여 대상 서버에 전달한다.
사용 : 클라이언트 코드에서 /api
로 시작하는 경로를 대상 서버의 실제 경로로 변경할 때 사용한다.