icon

네임스페이스 사용법


 타입스크립트의 네임스페이스는 관련된 기능을 그룹화하고 전역 스코프의 오염을 방지하기 위한 메커니즘입니다.

 모듈 시스템과 달리, 네임스페이스는 논리적 그룹화에 중점을 둡니다.

네임스페이스 기본 개념

 네임스페이스의 기본 문법

namespace MyNamespace {
    export interface MyInterface {
        myProperty: string;
    }
 
    export class MyClass implements MyInterface {
        constructor(public myProperty: string) {}
    }
 
    export function myFunction() {
        console.log("Hello from MyNamespace");
    }
}
 
// 사용
const instance = new MyNamespace.MyClass("Hello");
MyNamespace.myFunction();

 네임스페이스는 export 키워드로 외부에 노출할 요소를 지정합니다.

네임스페이스 vs 모듈

 주요 차이점

  1. 스코프 : 네임스페이스는 전역 스코프, 모듈은 파일 스코프
  2. 로딩 : 네임스페이스는 런타임에 전역으로 사용 가능, 모듈은 명시적 임포트 필요
  3. 의존성 관리 : 모듈이 더 명시적이고 관리하기 쉬움

중첩 네임스페이스

 네임스페이스는 중첩하여 사용할 수 있습니다.

namespace Outer {
    export namespace Inner {
        export class InnerClass {}
    }
    export class OuterClass {}
}
 
// 사용
const inner = new Outer.Inner.InnerClass();
const outer = new Outer.OuterClass();

 이 방식은 복잡한 라이브러리의 구조를 표현할 때 유용합니다.

네임스페이스 분할과 의존성 관리

 여러 파일에 걸쳐 네임스페이스를 분할할 수 있습니다.

// file1.ts
namespace MyNamespace {
    export function func1() {}
}
 
// file2.ts
/// <reference path="file1.ts" />
namespace MyNamespace {
    export function func2() {
        func1(); // 같은 네임스페이스 내에서 직접 접근 가능
    }
}

 /// <reference> 지시문은 컴파일러에게 의존성을 알려줍니다.

네임스페이스와 모듈의 하이브리드 사용

 네임스페이스와 모듈을 함께 사용할 수 있지만, 주의가 필요합니다.

// myModule.ts
export namespace MyNamespace {
    export function myFunction() {}
}
 
// main.ts
import { MyNamespace } from './myModule';
MyNamespace.myFunction();

 이 접근 방식은 레거시 코드와의 호환성을 유지할 때 유용할 수 있지만, 일반적으로 권장되지 않습니다.

네임스페이스 별칭

 긴 네임스페이스 경로를 단축할 수 있습니다.

namespace VeryLong.Nested.Namespace {
    export function myFunction() {}
}
 
import VNN = VeryLong.Nested.Namespace;
VNN.myFunction();

라이브러리 구조화

 네임스페이스를 사용한 라이브러리 구조화 예

namespace MyLibrary {
    export namespace Utils {
        export function helperFunction() {}
    }
 
    export namespace Models {
        export interface User {}
    }
 
    export namespace Services {
        export class UserService {
            getUser(): Models.User {
                Utils.helperFunction();
                return {} as Models.User;
            }
        }
    }
}

 이 방식의 장점은 관련 기능을 논리적으로 그룹화할 수 있다는 것입니다.

 다만 모듈 시스템에 비해 의존성 관리가 어렵다는 점이 단점으로 작용합니다.

네임스페이스와 ES 모듈 상호 운용성

 네임스페이스와 ES 모듈을 함께 사용할 때는 주의가 필요합니다.

// namespace.ts
namespace MyNamespace {
    export const myConst = 42;
}
 
// module.ts
export { MyNamespace } from './namespace';
 
// main.ts
import { MyNamespace } from './module';
console.log(MyNamespace.myConst); // 42

 이 방식은 작동하지만, 모듈 시스템만 사용하는 것이 더 명확하고 관리하기 쉽습니다.

컴파일러 옵션

 네임스페이스 관련 주요 컴파일러 옵션

  • --outFile : 여러 네임스페이스 파일을 하나의 파일로 컴파일
  • --module : 모듈 시스템 지정 (네임스페이스 사용 시 'none' 또는 'amd' 권장)
{
    "compilerOptions": {
        "outFile": "./dist/bundle.js",
        "module": "none"
    }
}

현대적 개발 환경에서의 대안

 현대 타입스크립트 개발에서는 네임스페이스 대신 ES 모듈을 사용하는 것이 권장됩니다.

utils.ts
export function helperFunction() {}
models.ts
export interface User {}
services.ts
import { helperFunction } from './utils';
import { User } from './models';
 
export class UserService {
    getUser(): User {
        helperFunction();
        return {} as User;
    }
}

 이 접근 방식은 더 나은 의존성 관리와 트리 쉐이킹을 가능하게 합니다.

Best Practices와 주의사항

  1. 모듈 선호 : 가능한 한 네임스페이스 대신 ES 모듈 사용
  2. 일관성 유지 : 프로젝트 내에서 네임스페이스와 모듈을 혼용하지 않기
  3. 얕은 중첩 : 네임스페이스를 사용할 경우, 중첩을 최소화
  4. 명확한 이름 : 충돌을 피하기 위해 명확하고 고유한 네임스페이스 이름 사용
  5. 레거시 고려 : 레거시 시스템과의 통합 시에만 제한적으로 사용
  6. 문서화 : 네임스페이스 사용 시 그 이유와 구조를 명확히 문서화
  7. 점진적 마이그레이션 : 기존 네임스페이스 기반 코드는 점진적으로 모듈 시스템으로 전환

네임스페이스의 현재 위치

 네임스페이스는 타입스크립트의 초기 버전에서 중요한 역할을 했지만, 현재는 그 사용이 권장되지 않습니다.

 주요 이유는 다음과 같습니다.

  1. 모듈 시스템의 발전 : ES 모듈이 표준화되고 널리 지원됨
  2. 번들러의 발전 : Webpack, Rollup 등이 모듈 기반 코드를 효율적으로 처리
  3. 의존성 관리 : 모듈 시스템이 더 명시적이고 관리하기 쉬움
  4. 생태계 지원 : 대부분의 현대 도구와 라이브러리가 모듈 시스템을 기반으로 함

 그럼에도 불구하고 네임스페이스는 여전히 다음과 같은 상황에서 사용될 수 있습니다.

  • 레거시 시스템과의 통합
  • 전역 라이브러리 API 설계 (드문 경우)
  • 특정 런타임 환경에서의 제약 사항

 새로운 타입스크립트 프로젝트를 시작할 때는 ES 모듈 시스템을 사용하는 것이 가장 좋은 선택입니다.

 네임스페이스는 역사적인 이유로 여전히 지원되지만, 현대적인 웹 개발 실무에서는 점점 그 자리를 모듈 시스템에 내주고 있습니다.

 기존의 네임스페이스 기반 코드베이스를 유지보수하거나 마이그레이션해야 하는 경우가 아니라면 네임스페이스 사용을 피하고 모듈 시스템을 채택하는 것이 장기적으로 더 나은 선택일 것입니다.