--define 플래그를 사용하면 정적으로 분석 가능한 상수와 전역 변수를 선언할 수 있습니다. 이는 JavaScript 또는 TypeScript 파일에서 식별자나 속성의 모든 사용을 상수 값으로 대체합니다. 이 기능은 런타임과 bun build 에서 모두 지원됩니다. 이는 C/C++ 의 #define 과 유사하지만 JavaScript 용입니다.
bun --define process.env.NODE_ENV="'production'" src/index.ts # 런타임
bun build --define process.env.NODE_ENV="'production'" src/index.ts # 빌드이러한 정적으로 알려진 값은 Bun 이 데드 코드 제거 및 기타 최적화에 사용합니다.
if (process.env.NODE_ENV === "production") {
console.log("Production mode");
} else {
console.log("Development mode");
}코드가 JavaScript 엔진에 도달하기 전에 Bun 은 process.env.NODE_ENV 를 "production" 으로 대체합니다.
if ("production" === "production") {
console.log("Production mode");
} else {
console.log("Development mode");
}여기서 멈추지 않습니다. Bun 의 최적화된 트랜스파일러는 일부 기본 상수 폴딩을 수행할 만큼 충분히 똑똑합니다.
"production" === "production" 은 항상 true 이므로 Bun 은 전체 표현식을 true 값으로 대체합니다.
if (true) {
console.log("Production mode");
} else {
console.log("Development mode");
}마지막으로 Bun 은 else 분기에 도달할 수 없음을 감지하고 이를 제거합니다.
console.log("Production mode");어떤 유형의 값이 지원되나요?
값은 문자열, 식별자, 속성 또는 JSON 일 수 있습니다.
전역 식별자 대체
window 의 모든 사용을 undefined 로 만들려면 다음 명령을 사용할 수 있습니다.
bun --define window="undefined" src/index.ts이는 서버 사이드 렌더링 (SSR) 을 하거나 코드가 window 객체에 의존하지 않도록 할 때 유용할 수 있습니다.
if (typeof window !== "undefined") {
console.log("Client-side code");
} else {
console.log("Server-side code");
}값을 다른 식별자로 설정할 수도 있습니다. 예를 들어 global 의 모든 사용을 globalThis 로 만들려면 다음 명령을 사용할 수 있습니다.
bun --define global="globalThis" src/index.tsglobal 은 Node.js 의 전역 객체이지만 웹 브라우저에서는 그렇지 않습니다. 따라서 global 을 사용할 수 있다고 가정하는 코드의 일부 경우를 수정할 수 있습니다.
값을 JSON 으로 대체
--define 은 값과 JSON 객체와 배열을 대체하는 데에도 사용할 수 있습니다.
AWS 의 모든 사용을 JSON 객체 {"ACCESS_KEY":"abc","SECRET_KEY":"def"} 로 대체하려면 다음 명령을 사용할 수 있습니다.
# JSON
bun --define AWS='{"ACCESS_KEY":"abc","SECRET_KEY":"def"}' src/index.ts이들은 동등한 JavaScript 코드로 변환됩니다.
다음에서:
console.log(AWS.ACCESS_KEY); // => "abc"다음으로:
console.log("abc");값을 다른 속성으로 대체
--define 플래그에 속성을 전달할 수도 있습니다.
예를 들어 console.write 의 모든 사용을 console.log 로 대체하려면 다음 명령을 사용할 수 있습니다.
bun --define console.write=console.log src/index.ts이는 다음 입력을 변환합니다.
console.write("Hello, world!");다음 출력으로:
console.log("Hello, world!");변수 설정과 어떻게 다른가요?
코드에서 process.env.NODE_ENV 를 "production" 으로 설정할 수도 있지만 데드 코드 제거에는 도움이 되지 않습니다. JavaScript 에서 속성 액세스는 부작용을 가질 수 있습니다. 게터와 세터는 함수일 수 있으며 동적으로 정의될 수도 있습니다 (프로토타입 체인과 Proxy 로 인해). process.env.NODE_ENV 를 "production" 으로 설정하더라도 다음 줄에서 정적 분석 도구가 process.env.NODE_ENV 가 "production" 이라고 가정하는 것은 안전하지 않습니다.
찾기 및 바꾸기 또는 문자열 대체와 어떻게 다른가요?
--define 플래그는 텍스트 수준이 아닌 AST(추상 구문 트리) 수준에서 작동합니다. 이는 트랜스파일 과정에서 발생하므로 데드 코드 제거와 같은 최적화에 사용할 수 있습니다.
문자열 대체 도구는 이스케이프 문제가 발생하거나 코드의 의도하지 않은 부분을 대체하는 경향이 있습니다.