Next.js 환경 변수 설정
환경 변수는 넥스트로 만든 애플리케이션을 배포할 때 알아두면 좋은 개념입니다. 상황에 따라서 필요한 값을 편하게 세팅할 수 있게 도와주기 때문이죠. 하나씩 살펴볼까요.
환경 변수를 써야 하는 이유?
대부분의 회사에서는 애플리케이션을 개발할 때 쓰는 내부 서버와 사용자에게 애플리케이션을 제공하는 외부 서버로 나뉘어져 있습니다. 예를 들면, 아래와 같이 말이죠.
# 내부 개발 서버
http://dev.booking.com/
# 사용자가 접속하는 사이트
http://booking.com/
위와 같이 서버가 나뉘게 된다면 프런트엔드 입장에서는 API를 호출하는 주소가 달라져야 할 겁니다. 이때 환경 변수를 이용해서 API 호출 주소를 유연하게 바꿀 수 있습니다.
환경 변수 기본
넥스트 프로젝트의 루트 레벨에 .env.local
파일을 추가합니다.
package.json
.env.local
.gitignore
그리고 파일 안에 다음 내용을 작성합니다.
API_URL=http://localhost:4000/api/v1
환경 변수는 이렇게 키=값
형태로 작성합니다. 중간에 공백 같은 건 넣지 않아야 합니다. 주석은 원한다면 #
로 추가할 수 있습니다.
이렇게 작성한 환경 변수는 코드에서 다음과 같이 접근할 수 있습니다.
async function fetchProducts() {
await fetch(`${process.env.API_URL}/products`);
}
process.env
라는 건 노드(Node.js) 환경 변수를 의미합니다. 넥스트는 노드 기반으로 동작하기 때문에 노드에서 제공하는 기본적인 기능을 사용할 수 있습니다.
서버별 환경 변수 설정
방금 살펴본 코드는 로컬 서버의 API 호출 주소를 입력한 것입니다. 그리고, 이 API_URL
값은 로컬 서버 시작 명령어를 실행했을 때만 유효합니다. 달리 말해, 애플리케이션을 배포하기 위해 빌드하고 서버를 실행할 때는 의미가 없다는 말이죠. 애플리케이션을 빌드할 때는 다음과 같이 .env.production
파일을 사용합니다.
API_URL=http://booking.com/api/v1
이 파일도 마찬가지로 프로젝트 루트 레벨에 추가하고 npm run build
와 같은 빌드 명령어를 수행하면, 애플리케이션 코드에 process.env.API_URL
로 정의된 값이 모두 http://booking.com/api/v1
로 변경됩니다.
이처럼 빌드 명령어를 실행할 때 주입할 값들은 모두 .env.production
으로 관리합니다.
환경 변수 유효 범위 관련 주의 사항
빌드용 환경 변수(.env.production
)를 사용할 때 주의할 점이 있습니다. 바로 환경 변수의 값이 서버 컴포넌트에만 적용된다는 점인데요. 브라우저에서 실행되는 클라이언트 컴포넌트는 process.env
값에 접근하지 못합니다. 따라서, 아래와 같은 코드에서는 undefined
값이 나옵니다.
'use client';
function CartButton({ product }) {
const addCart = () => {
console.log(process.env.NEXT_PUBLIC_API_URL); // undefined
}
return <button onClick={addCart}></button>
}
환경 변수 기본에서 설명했듯이 process.env
는 노드에서만 유효하기 때문에 어떻게 보면 당연합니다. 그럼, 클라이언트에서도 쓸 수 있는 환경 변수 설정 방법은 없을까요?
바로 NEXT_PUBLIC_
접두사를 붙이면 됩니다. 아래와 같이 말이죠.
NEXT_PUBLIC_API_URL=http://booking.com/api/v1
이렇게 하면 노드와 브라우저에서 모두 접근할 수 있는 환경 변수 값이 됩니다.
환경 변수 우선순위
여러 개의 환경 변수를 다룰 때 한가지 더 주의할 점이 있습니다. 바로 환경 변수 우선순위인데요. 앞에서 배운 내용들로 빠르게 환경 변수 체계를 구성하다가 만약 다음과 같이 해버린다면 문제가 발생합니다.
.env.local
.env.production
환경 변수를 로컬과 프로덕션 두개만 관리하게 되면 각 파일에 값을 구분해서 두어도 애플리케이션을 빌드할 때 .env.production
에 저장한 값이 인식되지 않게 됩니다. 그 이유는 다음과 같이 넥스트에서 환경 변수를 인식하는 순서가 있기 때문이죠.
process.env
.env.$(NODE_ENV).local
.env.local
- `.env.$(NODE_ENV)
.env
npm run build
명령어로 빌드를 실행해도 위 우선순위에 의해서 .env.local
이 먼저 인식됩니다. 이를 해결하려면 기본적으로 .env.local
보다는 .env.development
등을 사용하면 됩니다.
.env.development ← 로컬에서 `npm run dev`를 실행해도 인식됨
.env.production
노드에서 기본적으로 지원하는 NODE_ENV의 종류에는 development, test, production 세개가 있습니다.