TypeScript의 Enum은 일반적으로 열거형 상수들의 집합을 정의하는데 사용된다.
근데 build를 하고 어플리케이션을 Tree-shaking하는 과정에서 Enum은 Tree-shaking이 제대로 되지 않는다.
참고로 Tree-shaking이란 번들링된 코드에서 사용하지 않는 코드를 자동으로 제거하여 번들 크기를 줄이고 앱의 성능을 향상시키는 것이다.
예를 들어, 다음과 같이 두 개의 모듈이 있다고 가정해보자.
// math.js
export function square(x) {
return x * x;
}
export function cube(x) {
return x * x * x;
}
// main.js
import { square } from './math';
console.log(square(4));
이 예시에서 main.js 모듈은 math.js 모듈에서 제공하는 cube 함수를 사용하지 않는다.
따라서 트리 쉐이킹이 적용된다면 cube 함수는 번들에 포함되지 않는다.
트리 쉐이킹이 적용된 뒤의 번들 결과물은 다음과 같이 될 것이다.
// Optimized bundle
export function square(x) {
return x * x;
}
console.log(square(4));
enum
은 컴파일된 javascript 코드에서 실제로 객체로 변환된다.
예를 들어 다음과 같다.
enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
function getColor(): Color {
return Color.Green;
}
번들링 후 ..
var Color;
(function (Color) {
Color["Red"] = "RED";
Color["Green"] = "GREEN";
Color["Blue"] = "BLUE";
})(Color || (Color = {}));
function getColor() {
return Color.Green;
}
가시적으로 봐도 더 늘어나는 게 보인다...
이런 enum
이 더 추가될 수록 javascript의 번들 크기를 늘리게 될 것이고 사용자 경험에 악영향을 미치게 된다.
제대로 tree-shaking
이 되지 않는 이유는 객체에는 열거형 상수의 이름과 값이 포함되어 있는데, Tree-shaking은 정적으로 상수 값을 알 수 없는 상황에서는 해당 상수 값을 사용하지 않을지라도 제거할 수 없기 때문이다.
const enum
은 typescript에서 상수 열거형을 정의할 때 사용된다.
일반적으로 const enum
은 컴파일 시점에서 상수 값들을 직접 인라인으로 넣어준다. 이를 통해 런타임에 객체 생성 및 할당 없이도 상수 값들을 사용할 수 있다.
사용법은 간단하다.
const 만 붙이면 된다. ㅋㅋㅋ
const enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
const enum
의 장점const enum
은 컴파일 시점에서 인라인된 값으로 대체되므로, 코드의 어디에서나 해당 상수 값을 사용하더라도 실제 런타임에 객체 생성 없이도 사용 가능. 따라서 Tree-shaking이 효과적으로 동작하여 불필요한 코드를 제거 가능const enum
을 사용하면 번들 크기를 줄일 수 있습니다. 컴파일된 코드에서 상수 값들이 중복되거나 반복적으로 포함되지 않으므로 번들 크기가 작아지는 효과가 있습니다.단, 단점도 있다.
일단 const enum
은 컴파일된 코드에 상수 값들이 직접 들어가기 때문에 해당 값들이 그대로 노출된다.
노출된다는 게 무슨 의미인가?
const enum
값을 사용하는 경우, 그 코드는 컴파일 시에 해당 값이 직접 인라인되어 포함const enum
값이 변경된다면, 해당 라이브러리를 사용하는 모든 코드를 다시 컴파일해야 함const enum
값을 사용하면 네임스페이스 충돌이 발생할 수 있다.const enum
값을 사용하면, 컴파일 시 충돌이 일어나 오류가 발생할 수 있다. 리터럴 타입의 유니온
사용개발할 때는 가장 길어지니깐 더럽긴 한데,,, 가장 성능이 좋다.
export const ORDER = {
recent: 'recent',
popular: 'popular',
downloads: 'downloads',
} as const;
export type ORDER_TYPE = typeof ORDER[keyof typeof ORDER];
Union Type
쓰자 !
참고: