배포환경이 dev 서버와 실서버가 구분되어 있을 때, 사용 하는 환경변수들을 다르게 설정해야 되는 경우가 있다.
예를 들어 Api url 이 prodution 서버는 example.co.kr 이고, dev 서버는 dev.example.co.kr 일 수가 있는데 이럴때는 env 파일을 따로 분리해서 유동적인 환경변수를 사용해야 한다.
CRA으로 사용할 수 있는 env 파일은 아래와 같다.
.env: 기본..env.local: 로컬 override. 이 파일은 test를 제외한 모든 환경에 대해 로드된다..env.development, .env.test, .env.production: 환경별 설정..env.development.local, .env.test.local, .env.production.local: 환경별 설정의 로컬 override.이때, script 명령어 별 env 파일 우선순위는 아래와 같다.
.env.development.local, .env.local, .env.development, .env.env.production.local, .env.local, .env.production, .env.env.test.local, .env.test, .env여기서 발생하는 문제는 CRA을 사용한 프로젝트에서 env 파일을 사용하는 우선순위는 위와같이 CRA에서 등록한 명령어에 따라 정해져 있으며 이것은 override로 커스터마이징 할 수 가 없다는 것이다... 😱
(CRA 공식문서)

그래서 배포시 build 를 할때에 아래와 같이 build:dev 는 .env.development 을 실행하고 싶고 build:prod 는 .env.production 을 실행하고 싶은 상황이 와도, build 라는 명령어는 무조건 .env.production 를 실행하게 되어있다......
"scripts": {
"build:prod": "NODE_ENV=production react-script build",
"build:dev": "NODE_ENV=development react-script build"
}
환경변수를 build 시에 분기할 수 있는 방법이 뭐 없을까 서치해 보다가 이 깃허브 이슈를 보고 env-cmd 라이브러리를 사용하는 게 해결책이라는 힌트를 얻었다.
위 이슈 스레드에서 이렇게 답한 사람의 글을 보고 좀더 자세히 이해할 수 있었다.

CRA은 내부적으로 dotenv 라는 라이브러리를 사용한다.
때문에 "start": "MY_ENV=123 react-script start" 이렇게 명령어 줄에 직접 작성하면 CRA 에서 어떤 env 파일을 실행하는 지와 상관 없이 yarn start 명령어로 실행했을 때 MY_ENV 의 값은 항상 123 이 된다.
다만 좀 더 첨언을 하자면, "CRA을 사용했을 경우" 환경변수 이름은 반드시 REACT_APP_ 으로 시작해야만 적용되기 때문에 정확히는 REACT_APP_MY_ENV 로 작성해야 아래처럼 제대로 된 결과를 확인할 수 있다.
package.json ⬇️

console.log 결과 ⬇️

env-cmd 라이브러리도 위와 동일한 원리로 작동하며, 명령줄에 환경 변수를 모두 나열하는 대신 파일에 환경 변수를 넣을 수 있게 해준다. 따라서 env-cmd 로 지정한 .env 파일의 모든 환경 변수는 cmd 명령줄에서 사용되고, CRA가 사용하는 모든 env 파일보다 우선시 한다.
서론이 길었는데 사실 지금부터 본격적인 사용방법의 설명이다.
env-cmd 라이브러리를 설치해 준다.
yarn add env-cmd
root 위치인 /src 파일에 .env.development 파일과 .env.production 파일을 생성하고 아래와 같이 환경변수를 각각 등록한다.

package.json 파일을 아래와 같이 수정해준다.
"scripts": {
"build:prod": "react-script build",
"build:dev": "env-cmd -f .env.development react-script build",
...
}
이제 프로젝트 내 파일에서 process.env.<NAME> 을 통해 build 스크립트 별 다른 환경변수를 사용할 수 있다.
개인적으로는 Production 서버 여부를 확인하는 코드는 사용 빈도가 높음으로 utils 폴더 파일에 아래와 같이 isProduction 변수를 따로 등록해서 사용하는 것을 선호한다.
export const isProduction = process.env.REACT_APP_MODE === 'production';
위 세팅이 모두 끝난 후build:dev 명령어를 통해 환경변수를 console.log 한 결과이다.


주의할 점은, process.env.NODE_ENV 자체는 보다싶이 production 이고, 변경되지 않았다. 아마도 CRA에서 내부적으로 세팅된 env 파일은 그대로이기 때문인 것 같다.
대신에 .env.production 파일 안에 등록된 환경 변수들 값은 .env.development 파일의 환경변수로 override 되었다.
이제 배포 환경은 REACT_APP_MODE 값을 통해 확인할 수 있다.