사용자 도구

사이트 도구


typescript:module

문서의 이전 판입니다!


Module

용어에 대한 노트: TypeScript 1.5에서 기록해둘 만큼 중요한 명명법 변경이 있었습니다. “내부 모듈(Internal modules)”은 “네임스페이스”가 되었습니다. “외부 모듈(External modules)”은 이제 간단하게 “모듈(modules)”이 되어 ECMAScript 2015의 용어와 맞췄습니다. (module X {namespace X {와 동일하며 후자가 선호됩니다.)

Introduction

ECMAScript 2015부터 JavaScript에는 모듈 개념이 있습니다. TypeScript는 이 개념을 공유합니다.

모듈은 전역 범위가 아닌 자체 범위 내에서 실행됩니다. 이는 모듈에서 선언 된 변수, 함수, 클래스 등이 내보내기 양식 중 하나를 사용하여 명시 적으로 내보내지지 않으면 모듈 외부에서 볼 수 없음을 의미합니다. 반대로, 다른 모듈에서 내 보낸 변수, 함수, 클래스, 인터페이스 등을 사용하려면 import forms 중 하나를 사용하여 가져와야합니다.

모듈은 선언적입니다. 모듈 간의 관계는 파일 수준에서 가져 오기 및 내보내기 측면에서 지정됩니다.

모듈은 모듈 로더를 사용하여 서로를 가져옵니다. 런타임시 모듈 로더는 모듈을 실행하기 전에 모듈의 모든 종속성을 찾고 실행합니다. 자바 스크립트에서 사용되는 잘 알려진 모듈 로더는 CommonJS모듈용 Node.js로더와 웹 애플리케이션에서 AMD모듈용 RequireJS로더입니다.

TypeScript에서는 ECMAScript 2015와 마찬가지로 최상위 import 또는 export가 포함 된 파일을 모듈로 간주합니다. 반대로, 최상위 import 또는 export 선언이 없는 파일은 내용이 전역 범위에서 사용할 수있는 스크립트로 취급되므로 모듈에서도 마찬가지입니다.

Export

Exporting a declaration

export 키워드를 추가하여 모든 선언 (예 : 변수, 함수, 클래스, 유형 별명 또는 인터페이스)을 내보낼 수 있습니다.

StringValidator.ts
export interface StringValidator {
    isAcceptable(s: string): boolean;
}
ZipCodeValidator.ts
import { StringValidator } from "./StringValidator";
 
export const numberRegexp = /^[0-9]+$/;
 
export class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }

Export statements

Export 문장은 소비자의 이름을 바꿀 필요가 있을 때 유용하므로 위의 예는 다음과 같이 작성 될 수 있습니다.

class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator };

Re-exports

종종 모듈은 다른 모듈을 확장하고 일부 기능을 부분적으로 노출합니다. 다시 내보내기는 로컬로 가져 오기하거나 로컬 변수를 가져 오지 않습니다.

ParseIntBasedZipCodeValidator.ts
export class ParseIntBasedZipCodeValidator {
    isAcceptable(s: string) {
        return s.length === 5 && parseInt(s).toString() === s;
    }
}
 
// Export original validator but rename it
export {ZipCodeValidator as RegExpBasedZipCodeValidator} from "./ZipCodeValidator";

선택적으로 모듈은 하나 이상의 모듈을 랩핑하고 export * from “module”를 사용하여 모든 내보내기를 결합 할 수 있습니다.

AllValidator.ts
export * from "./StringValidator"; // exports 'StringValidator' interface
export * from "./ZipCodeValidator";  // exports 'ZipCodeValidator' and const 'numberRegexp' class
export * from "./ParseIntBasedZipCodeValidator"; //  exports the 'ParseIntBasedZipCodeValidator' class
                                                 // and re-exports 'RegExpBasedZipCodeValidator' as alias
                                                 // of the 'ZipCodeValidator' class from 'ZipCodeValidator.ts'
                                                 // module.

Import

가져 오기는 모듈에서 내보내기만큼 쉽습니다. 내 보낸 선언을 가져 오려면 아래 가져 오기 양식 중 하나를 사용하십시오.

Import a single export from module

import { ZipCodeValidator } from "./ZipCodeValidator";
let myValidator = new ZipCodeValidator();

imports는 또한 개명가능하다.

import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
let myValidator = new ZCV();

import는 전체 module을 한 변수로 받아서 export된 module을 접근할 수 있다.

import * as validator from "./ZipCodeValidator";
let myValidator = new validator.ZipCodeValidator();

Import a module for side-effects only

권장 사항은 아니지만 일부 모듈은 다른 모듈에서 사용할 수있는 일부 전역 상태를 설정합니다. 이 모듈에는 수출이 없거나 소비자가 수출에 관심이 없습니다. 이러한 모듈을 가져 오려면 다음을 사용하십시오.

import "./my-module.js";

Default exports

각 모듈은 선택적으로 default 내보내기를 내보낼 수 있습니다. default 내보내기는 키워드 default로 표시됩니다. 모듈 당 하나의 default 내보내기 만있을 수 있습니다. default import는 다른 import form을 사용하여 가져옵니다.

default 내보내기은 정말 편리합니다. 예를 들어, jQuery와 같은 라이브러리에는 jQuery 또는 $의 기본 내보내기가있을 수 있습니다. $ 또는 jQuery라는 이름으로 가져올 수도 있습니다.

JQuery.d.ts
declare let $: JQuery;
export default $;
App.ts
import $ from "jquery";
$("button.continue").html("Next Step...");

클래스 및 함수 선언은 기본 내보내기로 직접 작성 될 수 있습니다. 기본 내보내기 클래스 및 함수 선언 이름은 선택 사항입니다.

ZipCodeValidator.ts
export default class ZipCodeValidator {
  static numberRegexp = /^[0-9]+$/;
  isAcceptable(s: string) {
    return s.length === 5 && ZipCodeValidator.numberRegexp.test(s);
  }
}
Test.ts
import validator from "./ZipCodeValidator";
 
let myValidator = new validator();

or

StaticZipCodeValidator.ts
const numberRegexp = /^[0-9]+$/;
 
export default function (s: string) {
  return s.length === 5 && numberRegexp.test(s);
}
Test.ts
import validate from "./StaticZipCodeValidator";
 
let strings = ["Hello",  "98052", "101"];
 
// Use function validate
string.forEach(s => {
  console.log(`"${s}" ${validate(s) ? " matches" : " does not match"}`);
});

default내보내기는 값도 가능하다.

OneTwoThree.ts
export default "123";
Log.ts
import num from "./OneTwoThree";
 
console.log(num); // "123"

export = 와 import = require()

CommonJS와 AMD 모두 일반적으로 모듈의 모든 내보내기를 포함하는 exports 개체 개념을 가지고 있습니다.

또한 exports 개체를 사용자 지정 단일 개체로 바꾸는 기능도 지원합니다. 기본 내보내기는 이 동작을 대신하는 역할을합니다. 그러나 두 개는 호환되지 않습니다. TypeScript는 일반적인 CommonJS 및 AMD 워크 플로우를 모델링하기 위해 export =를 지원합니다.

export = 구문은 모듈에서 내 보낸 단일 객체를 지정합니다. 클래스, 인터페이스, 네임 스페이스, 함수 또는 열거 형이 될 수 있습니다.

export =를 사용하여 모듈을 내보낼 때, 모듈 가져 오기에는 TypeScript 특정 import module = require ( “module”)을 사용해야합니다.

ZipCodeValidator.ts
let numberRegexp = /^[0-9]+$/;
class ZipCodeValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export = ZipCodeValidator;
Test.ts
import zip = require("./ZipCodeValidator");
 
// Some samples to try
let strings = ["Hello", "98052", "101"];
 
// Validators to use
let validator = new zip();
 
// Show whether each string passed each validator
strings.forEach(s => {
  console.log(`"${ s }" - ${ validator.isAcceptable(s) ? "matches" : "does not match" }`);
});

Code Generation for Modules

컴파일하는 동안 지정된 모듈 타겟에 따라 컴파일러는 Node.js (CommonJS), require.js (AMD), UMD, SystemJS 또는 ECMAScript 2015 네이티브 모듈 (ES6) 모듈로드 시스템에 적합한 코드를 생성합니다. 생성 된 코드에서 define, requireregister 호출에 대한 자세한 내용은 각 모듈 로더에 대한 설명서를 참조하십시오.

이 간단한 예제는 가져 오기 및 내보내기 중에 사용 된 이름이 모듈 로딩 코드로 어떻게 변환되는지 보여줍니다.

SimpleModule.ts
import m = require("mod")
export let t = m.something + 1;
AMD/RequireJS SimpleModule.js
define(["require", "exports", "./mod"], function (require, exports, mod_1) {
  exports.t = mod_1.something + 1;
});
CommonJS / Node SimpleModule.js
var mod_1 = require("./mod");
exports.t = mod_1.something + 1;
UMD SimpleModule.js
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports); if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "./mod"], factory);
    }
})(function (require, exports) {
    var mod_1 = require("./mod");
    exports.t = mod_1.something + 1;
});
System SimpleModule.js
System.register(["./mod"], function(exports_1) {
    var mod_1;
    var t;
    return {
        setters:[
            function (mod_1_1) {
                mod_1 = mod_1_1;
            }],
        execute: function() {
            exports_1("t", t = mod_1.something + 1);
        }
    }
});
Native ECMAScript 2015 modules SimpleModule.js
import { something } from "./mod";
export var t = something + 1;

Simple Example

아래에서는 앞의 예제에서 사용 된 유효성 검사기 구현을 통합하여 각 모듈에서 하나의 명명 된 내보내기 만 내보내도록했습니다.

컴파일하려면 명령 줄에 모듈 대상을 지정해야합니다. Node.js의 경우 –module commonjs를 사용하십시오. require.js에 대해 –module amd를 사용하십시오.

예 :

tsc --module commonjs Test.ts

컴파일되면 각 모듈은 별도의 .js 파일이됩니다. 참조 태그와 마찬가지로 컴파일러는 import 문을 따라 종속 파일을 컴파일합니다.

Validation.ts
export interface StringValidator {
    isAcceptable(s: string): boolean;
}
LettersOnlyValidator.ts
import { StringValidator } from "./Validation";
 
const lettersRegexp = /^[A-Za-z]+$/;
 
export class LettersOnlyValidator implements StringValidator {
    isAcceptable(s: string) {
        return lettersRegexp.test(s);
    }
}
ZipCodeValidator.ts
import { StringValidator } from "./Validation";
 
const numberRegexp = /^[0-9]+$/;
 
export class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
Test.ts
import { StringValidator } from "./Validation";
import { ZipCodeValidator } from "./ZipCodeValidator";
import { LettersOnlyValidator } from "./LettersOnlyValidator";
 
// Some samples to try
let strings = ["Hello", "98052", "101"];
 
// Validators to use
let validators: { [s: string]: StringValidator; } = {};
validators["ZIP code"] = new ZipCodeValidator();
validators["Letters only"] = new LettersOnlyValidator();
 
// Show whether each string passed each validator
strings.forEach(s => {
    for (let name in validators) {
        console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`);
    }
});

Optional Module Loading and Other Advanced Loading Scenarios

경우에 따라서 어떤 조건에서만 모듈을 로드를 원할 수 있습니다. TypeScript에서는 타입 안전성을 유지하면서 모듈 로더를 직접 호출 할 수 있도록 다음과 같은 고급로드 시나리오를 구현하기 위해 아래에 표시된 패턴을 사용할 수 있습니다.

컴파일러는 각 모듈이 방출된(emitted) JavaScript에서 사용되는지 여부를 감지합니다. 모듈 식별자가 타입 주석의 일부로 만 사용되고 식이 아닌 경우에는 해당 모듈에 대한 호출이 필요하지 않습니다. 사용하지 않는 참조를 제거하면 좋은 성능 최적화를 얻을 수 있으며 해당 모듈을 선택적으로 로드 할 수 있습니다.

이 패턴의 핵심 아이디어는 import id = require(“…”) 문을 사용하면 모듈에 의해 노출 된 유형에 액세스 할 수 있다는 것입니다. 모듈 로더는 아래의 if 블록 에서처럼 동적으로 호출됩니다 (require를 통해). 이는 레퍼런스-엘리먼 지 최적화를 활용하므로 필요한 경우에만 모듈이로드됩니다. 이 패턴이 작동하려면 import를 통해 정의 된 기호가 타입 위치에서만 사용되어야합니다 (즉, 자바 스크립트로 전송되는 위치에 절대 사용되지 않음).

타입 안전성을 유지하기 위해 typeof 키워드를 사용할 수 있습니다. typeof 키워드를 타입 위치에서 사용하면 값 타입 (이 경우 모듈 타입)이 생성됩니다.

Dynamic Module Loading in Node.js
declare function require(moduleName: string): any;
 
import { ZipCodeValidator as Zip } from "./ZipCodeValidator";
 
if (needZipValidation) {
    let ZipCodeValidator: typeof Zip = require("./ZipCodeValidator");
    let validator = new ZipCodeValidator();
    if (validator.isAcceptable("...")) { /* ... */ }
}
Sample: Dynamic Module Loading in require.js
declare function require(moduleNames: string[], onLoad: (...args: any[]) => void): void;
 
import * as Zip from "./ZipCodeValidator";
 
if (needZipValidation) {
    require(["./ZipCodeValidator"], (ZipCodeValidator: typeof Zip) => {
        let validator = new ZipCodeValidator.ZipCodeValidator();
        if (validator.isAcceptable("...")) { /* ... */ }
    });
}
Sample: Dynamic Module Loading in System.js
declare const System: any;
 
import { ZipCodeValidator as Zip } from "./ZipCodeValidator";
 
if (needZipValidation) {
    System.import("./ZipCodeValidator").then((ZipCodeValidator: typeof Zip) => {
        var x = new ZipCodeValidator();
        if (x.isAcceptable("...")) { /* ... */ }
    });
}

Working with Other JavaScript Libraries

TypeScript로 작성되지 않은 라이브러리의 모양을 설명하려면 라이브러리가 노출하는 API를 선언해야합니다.

구현을 “ambient”으로 정의하지 않는 선언을 호출합니다. 일반적으로 .d.ts파일에 정의되어 있습니다. C/C ++에 익숙하다면이 파일을 .h 파일로 생각할 수 있습니다. 몇 가지 예를 살펴 보겠습니다.

주변 모듈(Ambient Modules)

Node.js에서 대부분의 작업은 하나 이상의 모듈을로드하여 수행됩니다. 최상위 수준의 내보내기 선언을 사용하여 각 모듈을 자체 .d.ts 파일로 정의 할 수 있지만 더 큰 .d.ts 파일로 작성하는 것이 더 편리합니다. 그렇게하기 위해, 우리는 앰비언트 네임 스페이스와 비슷한 구조를 사용하지만, module 키워드와 추후 가져올 수있는 모듈의 인용된 이름을 사용합니다.

예 :

node.d.ts(simplified excerpt)
declare module "url" {
    export interface Url {
        protocol?: string;
        hostname?: string;
        pathname?: string;
    }
 
    export function parse(urlStr: string, parseQueryString?, slashesDenoteHost?): Url;
}
 
declare module "path" {
    export function normalize(p: string): string;
    export function join(...paths: any[]): string;
    export var sep: string;
}

이제 / <reference> node.d.ts참조할 수 있고 import url = require(“url”); 또는 import * as URL from “url”을 사용하여 모듈을 로드할 수 있다.

typescript/module.1564467405.txt.gz · 마지막으로 수정됨: 2025/04/15 10:05 (바깥 편집)