개발 모드에 대해 알아야 할 점
개발 모드 (Development mode)의 동작 원리 중 팁으로 알고 있고 적용하기 좋은 포인트를 정리 해봤습니다.
NHN 토스트에서 번역한 댄 아브라모브의 글 - 개발 모드는 어떻게 작동할까? 를 보고 기억할 내역을 정리 및 요약한 글입니다.
개발 모드를 위한 환경 변수의 사용과 배포 환경과의 연관 관계에 대해 실질적으로 도움될 만한 부분이 있다고 생각하여 관련 글을 정리해봤습니다.
환경 변수의 역사
초기에 JS진영 환경 변수는
EXPRESS_ENV
로 시작됐습니다. 서버 사이드 어플레이케이션에서 설정을 구분하는 간단한 방법이었습니다.2010년에
NODE_ENV
가 등장하면서 노드 기반의 백엔드 개발에서 널리 채택 되기 시작했습니다.이후에는 2013년 부터 웹팩(Webpack)등의 모던 프론트엔드 빌드 툴과 함께 프론트엔드 개발에도 폭넓게 확산 되었습니다.
환경 변수의 동작 방식
- 환경 변수는 빌드 타임에 문자열로 치환 됩니다.
// .env
NODE_ENV=production
// app.js
if (process.env.NODE_ENV !== "production") {
doSomethingDev();
} else {
doSomethingProd();
}
- 위와 같이 써져 있으면 사실상 이것과 똑같이 동작합니다.
// .env
NODE_ENV=production
// app.js
if ("production" !== "production") {
doSomethingDev();
} else {
doSomethingProd();
}
죽은 코드 제거(Dead-code elimination)와 환경 변수
- 모던 자바스크립트 번들러는 배포 모드에서 죽은 코드를 제거하는 최적화 작업을 수행합니다. 환경 변수는 이 최적화 과정에서 중요한 역할을 합니다.
// 죽은 코드 제거가 적용된 위 예시
// .env
NODE_ENV=production
// app.js
doSomethingProd();
죽은 코드 제거를 활용할 때 주의 사항
import
문과 같은 모듈 시스템에서는 환경 변수를 바탕으로 한 조건부 코드 분기가 예상대로 동작하지 않을 수 있습니다. 모듈 시스템은 정적 구조를 가지기 떄문에 런타임에 조건을 바꿀 수 없기 때문입니다.
// .env
NODE_ENV=production
// app.js
// 절대 사용하지 않겠지만 제거된다는 보장은 없다.
import { someFunc } from "some-module";
if (process.env.NODE_ENV !== 'production') {
someFunc();
}
// 번들러가 모듈 전체를 하나의 단위로 처리하기 때문에,
// 특정 함수가 사용되지 않더라도 해당 모듈 전체를 최종 번들에 포함시킬 가능성이 높음
- 환경 변수를 직접 JS 변수에 할당하는 경우(let, const, var), 번들러가 해당 변수를 코드에서 제거하지 않을 수 있습니다.
// 환경 변수 값을 로컬 변수에 할당
const nodeEnv = process.env.NODE_ENV;
if (nodeEnv === 'production') { // 죽은 코드 제거 안됨
console.log('프로덕션 모드에서 실행 중');
} else {
console.log('개발 모드에서 실행 중');
}
개발 모드는 필수다
- 어플리케이션 개발 시 개발 모드는 디버깅과 오류 추적을 위해 필수적입니다. 개발 모드의 특성 상 성능이 느려지고, 일견 불필요해 보이는 경고 등이 많이 노출되겠지만 그럼에도 불구하고 치명적인 실수를 막아주기 때문입니다.
- 불필요해 보이지만 치명적인 예시: React key 경고가 없을 때의 위험성. 잘못된 상품을 구매하거나 잘못된 사람에게 메세지가 전송 되거나 이러한 인덱스로 인한 잠재적인 문제를 방지해 줍니다.
원 글이 훌륭하지만, 나름대로 재정리하고 관련 예시 코드도 작성해보았습니다.
끝까지 읽어주신 분들 감사합니다.