Javascript - 모듈

춤추는개발자·2023년 4월 26일
0
post-thumbnail

애플리케이션을 구성하는 각각의 요소로서 재사용 가능한 코드 조각을 모듈 이라고 합니다.

모듈은 기능을 기준으로 분리하여 각각의 파일에 작성 합니다.

이때 모듈은 모듈 자신만의 파일(모듈) 스코프를 가져야 하고 모듈의 자산(모듈 내에 구성되어 있는 모든 코드) 은 다른 모듈에서 접근 할 수 없으며 애플리케이션과 분리되어 존재합니다.

하지만 개별적으로 존재하는 모듈은 존재 의미가 없습니다. 애플리케이션이나 다른 모듈에서 모듈에 접근해 사용하도록 하여 재사용 되어야 모듈의 의미가 있을 것 입니다.

모듈은 공개를 원하는 자산에 한정하여 export 키워드로 선택적으로 공개가 가능하며 공개된 모듈을 사용하는 모듈을 모듈 사용자라고 합니다. 모듈 사용자는 공개된 모듈의 일부 또는 전체를 자신의 스코프로 불러와 사용할 수 있습니다.
이때 import 키워드를 사용해서 공개된 자산을 불러 옵니다.

이렇게 모듈은 개별적으로 분리되어 있다가 다른 모듈에 의해서 재사용 됩니다. 모듈을 사용하면 재사용성과 유지보수성을 높일 수 있습니다.

자바스크립트 모듈

분리되어 있는 자바스크립트 파일을 script 태그로 로드해도 하나의 자바스크립트 파일에 있는 것처럼 동작 합니다. 하지만 이렇게 되면 하나의 전역을 공유하기 때문에 전역 변수의 중복이 발생 할 수 있습니다.
코드로 확인 해 보면

// a.js
var a = 3;
// b.js
var a = 10;
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="./a.js"></script>
    <script src="./b.js"></script>
    <title>javascript</title>
  </head>
  <body>
    <script>
      console.log(a);
    </script>
  </body>
</html>

위의 변수 a 의 출력 결과는 10 입니다.

<script src="./b.js"></script>
<script src="./a.js"></script>

만약 script 태그의 순서를 바꾸면 변수 a 의 출력 결과는 3 입니다.

두 javascript 을 하나의 파일로 합치면 아래와 같이 되며

var a = 10;
var a = 3;
console.log(a);

a 변수가 중복 선언되어 의도치 않게 a 변수의 값을 덮어쓰게 되며 위와 같은 결과가 나오는 것 입니다.

html 파일에 각각의 javascript 파일을 로드해서는 모듈을 구현할 수 없습니다.


ES6 모듈

ES6 에서 클라이언트 사이드 자바스크립트에서도 동작하는 모듈 기능을 추가 했습니다.
이 기능의 사용법은 스크립트 태그의 type 으로 module 을 작성하고 불러오는 자바스크립트이 파일의 확장자를 js 가 아닌 mjs 사용하기를 권장하고 있습니다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script type="module" src="./b.js"></script>
    <script type="module" src="./a.js"></script>
    <title>javascript</title>
  </head>
  <body>
    <script>
      console.log(a);
    </script>
  </body>
</html>

위 html 파일에서 a 변수에 접근하면

아래와 같은 에러가 발생 합니다.
각각의 js 파일이 모듈화가 된 것을 확인 할 수 있습니다.

그리고 js 파일들을 모듈화 하기 전에는 모든 js 파일은 전역 스코프를 가지기 때문에 window.a 로 a 변수에 접근 할 수 있지만 모듈화를 하게되면 독자적인 모듈 스코프를 가지게 되어 전역변수가 아니게 됩니다.

export 키워드

모듈운 독자적인 모듈 스코프를 가지기 때문에 기본적으로 해당 모듈 내부에서만 참조가 가능 합니다.
모듈 내부의 식별자를 다른 모듈에서 접근하려면 export 키워드를 사용하여 외부에 식별자를 공개 해야 합니다.
export 키워드를 사용하는 방법은

// 파일 이름 abc.js 
export const a = 3;

export function b() {
  //
};

export class c {
  constructor(){
    //
  }
}

위와 같이 변수,함수,클래스를 export 키워드를 앞에 붙여 다른 모듈에 공개할 수 있습니다.

위의 식별자들을 각각의 export 키워드를 작성하지 않고

export {a,b,c};

하나의 객체로 한번에 export 할 수 있습니다.

import 키워드

자 그럼 export 로 인해서 공개된 모듈의 식별자를 다른 모듈에서 불러올때 어떻게 해야 할까요? 바로 import 키워드를 사용하는 것 입니다.

사용법은 간단합니다.

// 파일 이름 app.js
import {a,b,c} from "./abc.js";

자바스크립트 파일 가장 상단에 불러오고 싶은 모듈을 위와 같이 불러오면 됩니다.
그리고 바로 사용하면 됩니다.


import 의 의존성

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script type="module" src="./app.js"></script>
    <title>javascript</title>
  </head>
  <body>
    <script> 
      console.log(a);
    </script>
  </body>
</html>

위와 같이 html 파일에 script 태그로 app.js 파일을 로드 합니다.
그리고 body 태그 안에서 script 태그로 a 변수에 접근해 출력 합니다.

근데 html 파일에 abc.js 파일은 로드하지 않아도 될까요?
abc.js 파일은 app.js 파일에 import 하였기 때문에 의존성을 가지고 있다. 따라서 abc.js 파일은 html 파일에 따로 로드하지 않아도 됩니다.


모든 식별자 import

위와 같이 일일이 식별자를 하나씩 import 해야만 할까요?
하나의 이름으로 한번에 import 할 수 있는 방법은 없을까요?
있습니다.

import * as importItem from "abc.js";

위와 같이 as 뒤의 지정한 이름의 객체의 프로퍼티로 import 받을 수 있습니다.

export 할때 사용한 식별자 이름을 변경하여 사용할수도 있습니다.

import {a as A, b as B, c as C} from "./abc.js";

위와 같이 as 를 사용해 식별자 이름을 변경해서 사용할수도 있습니다.


default

모듈에서 하나의 식별자만 export 한다면 defalut 를 사용할 수 있습니다.
default 를 사용하면 이름 없이 값을 export 할 수 있고 var,let,const 키워드를 사용할 수 없습니다.

// 파일 이름 : abc.js
export default x => x+1;
// 파일 이름 : app.js
import onePlus from "./abc.js";

위와 같이 임의의 이름으로 import 받을 수 있습니다.


common js

node.js 환경에서 자바스크립트 모듈을 사용하기 위해 만든 모듈 시스템 입니다.
모듈을 외부에서 사용할 수 있도록 내보낼 때는 exports, module.exports 를 사용하고 외부에서 모듈을 불러올때는 require 를 사용하여 모듈을 불러올 수 있습니다.
현재는 node.js 환경에서도 ES6 모듈 시스템을 사용할 수 있습니다. node.js 환경에서 ES6 모듈 시스템을 사용하는 방법은 pakage.json 파일에 "type" : "module" 을 선언해주면 됩니다.

require 로 객체 형태로 받습니다.

// 파일 이름 abc.js 
exports.a = 3;
// 파일 이름 : app.js
const {a} = require("./abc.js");

console.log(a); // 3 

위와 같이 export 하고 싶은 키워드를 exports.식별자로 export 하고 require 로 객체 형태로 받을 수 있습니다.
각각의 exports.식별자 방법을 사용하지 않고 module.exports 방법을 사용해서 한번에 export 할 수 있는 방법이 있습니다. 아래의 코드를 확인해보겠습니다.

// 파일 이름 abc.js 
const a = 3;
const b = 10;

module.exports = {
  a,b,
}
// 파일 이름 : app.js
const {a,b} = require("./abc.js");

console.log(a); // 3 
console.log(b); // 10

이렇게 위와 같이 module.exports 를 사용해서 한번에 export 하고 싶은 식별자를 export 할 수 있습니다.

지금까지 정확하게 모르고 사용했던 export, import 를 알아 봤습니다.
모던 자바르스립트 deep Dive 책의 내용을 참고 하였습니다.

0개의 댓글