Typescript/TypeScript(ZeroCho)

JS 모듈 시스템

느리지만 꾸준하게 2021. 10. 21. 19:31

typescript의 모듈 시스템을을 알아보기전에 node js의 모듈 시스템을 먼저 알아보자.

 

node js의 모듈 시스템 common js가 있고 typescript이 따로 있는데

 

typescript의 모듈 시스템은 javascript 최신문법 es2015(es6) 모듈시스템을 그대로 계승했기 때문에 common js 모듈 시스템과 typescript(es2015 ) 모듈시스템 이 두개의 차이를 명확히 구분하자.

 

 

module과 script를 한번 구분해 보자.

html에서 script를 쓸 때 아래와 같이 쓴다.

<script src="module.js"></script>

그런데 이런 스크립트 말고 js파일 ts파일이 모듈이 될 수 있다. 

아래와 같이 module 값을 가진 hello 변수를 모듈로 만들고 싶다 그러면

// module.js
const hello = 'module';

 

common js에서 처럼 아래와 같이 하는 순간 모듈이 된다. 즉 노드에서는 module.exports를 붙이는 순간 다른 파일에서 hello를 사용할 수 있다. 사용해보자.

// module.js

const hello = 'module';

module.exports = hello;

run.js에서 아래와 같이 해보면 가져올 수 있다. 즉 모듈은 다른파일에서 사용할 수 있게 만들어준다.

파일이 쪼개지는 효과가 있는데 코딩을 하다보면 한 파일이 매우 길어지는데 그거를 가독성도 좋게하고 재사용성도 높이기 위해서 모듈로 만들어 주는 것이다. 이러한 모듈을 여러군데에서 require만 하면 재사용을 할 수 있기 때문에 편하게 쓸 수 있다.

// run.js

const hi = require("./module");

 

 

module.exports 말고 그냥 exports도 있다. 그냥 exports는 주로 객체를 exports할 때 아래와 같은 값이 있으면 

//module.js
const hello = "moduel";

exports.a = 'b';
exports.b = false;

 

다른 파일에서 import 할때는 {}로 묶어 주어야 한다. 왜냐 객체이기 때문에

// run.js
const { a, b } = require("./module");
console.log(hi);

 

exports가 객체이기 때문에 즉 객체 속성으로 모듈 값 두개를 넣어준거기 때문에 구조분해해서 가져와주어야 한다. 이렇게 두가지 방법이 있다. exports 하거나 아예 통채로 module.exports 하거나

// module.js

const hello = "moduel";

exports.a = "b";
exports.b = false;

module.exports = {
    a: 'b',
    b: false,
}

 

하지만 typescript는 common js를 안쓰는데 지금까지한 common js를 알아야 할까?

ts가 es2015 최신모듈 문법을 지원하지만 common js를 위한 문법도 지원하기 때문이다. 

 

common js랑 es2015 둘의 큰 차이는 default 부분과 dynamic인지 static인지 차이가 있는데 알아보기전에 다시한번 머릿속에 아래코드를 각인시키고 가자.

const hello = "moduel";

exports.a = "b";
exports.b = false;

module.exports = {
    a: 'b',
    b: false,
}

 

 

객체가 아니고 함수면 아래와 같이해서 할 수 있다. 여기서 module exports는 한번만 써야하는데 가장 중요한 코드가 module exports가 되기 때문이다.

 

그리고 exports와 module.exports 둘중에 하나만 쓰는 것이 좋다. exports와 module.exports는 같은 것인데 아래처럼 쓰게되면 함수로 덮어쓰기 때문에 exports a b 한 것이 사라져 버린다. 즉 run.js에서 a b를 require를 할 수 없게 된다.

// module.js

const hello = "moduel";

exports.a = "b";
exports.b = false;

module.exports = function() {
    
}




// run.js
const hi = require("./module");
console.log(hi);

 

es2015에는 default라는 것이있다.(위에 문제점을 극복하고자 나옴) es2015 모듈로 바꿔보자. 각각의 객체속성으로 export 하고자 하면 아래와 같이 나타낸다.

// module.js

const hello = "moduel";

const a = "b";
const b = false;

export { a };
export { b };
// run.js

import { a, b } from './module';

console.log(a, b)

 

또는 아래와 같이 나타낼 수 있다. 

// module.js

const hello = "moduel";

const b = false;

export const a = "b";
export { b };

 

 

최신문법에서 default라는게 생기고 module.exports는 사라졌다고 생각하자.

// module.js

const hello = "moduel";

const b = false;

export const a = "b";
export { b };

export default function () {


};
// run.js

import { a, b } from "./module";
import hi from "./module";

console.log(a, b);

console.log(hi());

 

아래와 같이 착각하지말자

const hello = "moduel";

const b = false;

export const a = "b";
export { b };

// 위에 것이 exports.a = 'b'; 이 코드와 같다? no



export default function () {


};

// module.exports = function() {}; 위 코드와 같다? no

 

즉 정리를 하면 module.exports는 default와 다르다. 그래서 module.exports를 쓰고 싶으면 아래와 같이 한다.

// module.js
const hello = "module";

module.exports = function () {};



// run.js
import * as hi from "./module";

console.log(hi());

 

만약에 아래와 같이 쓰고 싶으면 tsconfig.json에서 esModuleInterop: true를 켜야한다. 이거는 쓰지말자.

// run.js

import hi from "./module";

console.log(hi());
"esModuleInterop": true,

 

 

exportdefault인 경우에는 * as 빼고 아래와 같이 쓰자.

// module.js

const hello = "moduel";

const b = false;

export const a = "b";
export { b };

export default function () {}


// run.js
import hi from "./module";

console.log(hi());

 

 

 

 

<출처 조현영: 웹게임을 만들며 배우는 TypeScript>

https://www.inflearn.com/course/%EC%9B%B9%EA%B2%8C%EC%9E%84%EC%9D%84-%EB%A7%8C%EB%93%A4%EB%A9%B0-%EB%B0%B0%EC%9A%B0%EB%8A%94-typescript/dashboard

 

웹 게임을 만들며 배우는 TypeScript - 인프런 | 강의

웹 게임을 만들며 배우는 자바스크립트의 후속작으로 같은 게임을 타입스크립트로 만들어봅니다., 타입스크립트, 웹 게임을 만들며 재밌게 배워보아요! 🗒 강의소개 웹 게임을 만들며 배우는

www.inflearn.com

 

'Typescript > TypeScript(ZeroCho)' 카테고리의 다른 글

커스텀 패키지 타이핑  (0) 2021.10.21
남의 패키지인 Redux & Axios 사용하기  (0) 2021.10.21
TS 모듈 시스템의 주의사항  (0) 2021.10.21
tsc 기본명령어  (0) 2021.10.21
ts 간단한 변경사항  (0) 2021.10.21