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 모듈 시스템을 사용하는 것이 가장 좋은 선택입니다.

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

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