본문 바로가기

javascript/nodejs

dotenv - 환경변수 관리를 위한 라이브러리

 우리가 사용하는 컴퓨터 내부에는 특정 경로를 저장해두는 PATH, 운영체제의 정보를 가지는 OS 등 다양한 정보를 가지는 환경변수가 있다. node 환경에서도 process.env를 통해 이러한 환경 변수들에 접근할 수 있다.


process.env

https://nodejs.org/dist/latest-v16.x/docs/api/process.html#processenv

process.env은 유저의 환경 변수를 key-value 쌍으로 가지는 객체이다. 이때 해당 객체 내의 모든 키와 값의 쌍을 보고 싶다면 Object.entries 함수의 이용을 고려할 수 있다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

 Object.entries 함수는 입력받은 객체의 각 프로퍼티를 [ key, value ] 형태로 저장한 배열을 반환한다. 나의 환경에서 이를 해당 함수를 이용하여 process.env를 배열로 변환한 결과는 다음과 같다. 

process.env를 key-value 쌍의 배열로 변환한다.
환경변수는 개인적인 부분이 있어 일부만을 가져왔다.

 컴퓨터에서 사용되는 다양한 환경 변수들이 출력되고 있는 모습이다. 나의 환경이 윈도우이기 때문인지는 모르겠으나, 환경변수를 편집하는 칸에 명시되지 않은 다양한 환경 변수가 포함되어 있었으며, 등록되어 있는 환경변수가 무시되어 process.env에 반영되지 않는 경우도 보였다. 다른 사용법이 있을 것이라고 생각되지만, 공식 문서에도 별다른 내용이 없어 환경 변수를 가져올 때 일정한 규칙이 있는 것은 아닐까 하는 추측을 하게 된다.

 process.env에 직접 값을 넣을 수도 있다. 기본적으로 env는 일종의 객체이므로, Key-Value 형태로 값을 할당할 수 있다. 이때 자바스크립트에서는 크게 두가지 방법을 통해 객체에 값을 할당할 수 있었다.

  1. obj.KEY = VALUE : 점을 이용하여 프로퍼티에 값을 넣는다.
  2. obj['KEY'] = VALUE : 일종의 인덱스를 이용하여 값을 넣는다. 키에 규칙에 맞는 특수기호가 들어갈 수 있다.

 두가지 방법 중 어떤 방법을 사용하여 프로퍼티를 설정해도 상관 없지만, 대부분의 코드는 전자의 방식으로 작성된다. 아무튼 process.env에 값을 대입해본 결과는 다음과 같다.

env 객체에 정상적으로 값이 들어간 것을 볼 수 있다. 이처럼 process.env는 불변 객체가 아니기 때문에, 시스템 및 유저의 환경 변수를 가져오는 것 말고도 프로그램에서 사용될 수 있는 정보를 저장하기 위해 사용되기도 한다.


dotenv

 위 언급한 예시처럼 다양한 환경 변수를 자바스크립트 코드상에서 설정하는 방법도 있겠지만, 프로젝트 규모가 커질수록 여러 파일 내에서 분산하여 환경 변수들을 선언해 두는 것은 관리 면에서 좋지 않을 뿐더러 환경 변수의 형태로 구분하여 사용해야 할 정도로 중요한 정보를 코드상에 직접 노출하는 것은 결코 좋은 상황이 아니다.

 유지보수성 및 보안 측면의 문제로 인해 환경변수들은 특정 파일로 분리할 필요가 있는데, 이러한 동작을 도와주는 라이브러리 중 하나가 dotenv 라이브러리다. 해당 라이브러리가 하는 역할은 매우 간단한데, .env 파일로부터 환경변수 정보를 읽고, 해당 환경변수 값들을 process.env에 할당한다. 

해당 라이브러리는 아래 명령을 통해 설치할 수 있다.

npm install --save dotenv

 

사용법은 다음과 같다.

  • .env 파일을 만들고, KEY = VALUE 형태로 저장하고 싶은 환경 변수들을 적는다.
  • 코드 최상위에 import 'dotenv/config'; 을 덧붙인다.
  • process.env.KEY 의 형태로 환경 변수에 접근한다.

 

 데이터베이스의 ID 및 비밀번호를 저장하는 상황을 가정해보자. 이 경우 우리는 .env 파일 내에 ID 및 비밀번호와 같은 중요한 정보를 환경 변수로 저장할 수 있다. 이후 프로그램 코드 최상위에 import 'dotenv/config' 을 선언하고, 이후 해당 코드를 사용하면, 정상적으로 .env 파일 내부의 환경 정보가 출력되고 있는 모습을 볼 수 있다.

 대체 언제 .env 내부의 환경 변수가 process.env에 설정되는 걸까? 사실 dotenv/config 에서 config는 함수이다. 모듈을 로드할 때 require을 사용하는 경우 해당 함수에 특정 인자를 부여하여 실행할 수 있다.

const dotenv = require('dotenv');

const result = dotenv.config()

if (result.error) {
  throw result.error
}

 config 함수를 실행하면 .env의 정보를 읽어 process.env에 할당하는 작업을 수행한다. 해당 작업이 성공적으로 완료되면 파싱된 정보를 저장한 객체 혹은 에러를 반환하게 된다. 대부분의 상황에서는 파싱된 정보를 사용하지 않으므로, 'dotenv/config' 와 같은 방식으로 실행했을 뿐이다.

 import를 최상위에 두어야 하는 이유도 여기에 있다. import 'dotenv/config' 구문을 실행해야만 config 함수가 실행되어 .env 파일 내부에 저장된 환경 변수들이 process.env 파일 내부로 들어가므로, 해당 파일에 지정된 환경 변수를 사용하는 문장이 import보다 위에 있는 경우 해당 환경 변수는 지정되어 있지 않아 사용할 수 없기 때문이다.

config에 대해 지정할 수 있는 옵션들은 다음과 같다.

https://github.com/motdotla/dotenv#config

  • path : 읽어올 파일의 경로를 지정한다. 이 옵션을 이용하면 파일의 이름을 변경할 수 있다.
  • encoding : 해당 파일을 어떤 인코딩 방식으로 읽어올지 지정한다.
  • debug : 특정 키를 지정하면, 해당 키가 왜 설정되지 않았는지 알려준다고 한다.
  • override : 이미 존재하는 키도 덮어쓴다. ( 기본적으로 존재하는 키는 덮어쓰지 않는다. )
  • multiline : 여러 라인에 걸쳐 설정을 저장할 수 있게 된다. 설정은 큰따옴표 또는 작은따옴표로 덮는다.

 dotenv 라이브러리가 실행될 때는 몇가지 규칙이 존재한다.

  • 이미 설정된 환경 변수는 수정하지 않는다. ( 수정을 원하면 config의 설정에 override 추가 필요 )
  • 여러개의 .env 파일을 지원하지 않는다. ( 환경에 따라 설정 파일은 구분되어 있어야 한다는 원칙 )

라이브러리 자체가 전혀 어렵지 않고, 프로젝트에 유용하게 사용되므로 한번 알아두자.


요약

nodejs 환경에서 process.env 객체를 이용하면 시스템 및 유저의 환경 변수 정보를 얻을 수 있다.

dotenv 라이브러리는 환경 변수를 .env 파일로 분리하고, 해당 환경 변수들을 읽어오기 위한 목적으로 사용될 수 있다.