[자바스크립트 완벽가이드] - 모듈

Lee Jeong Min·2022년 6월 6일
1

자바스크립트

목록 보기
11/17
post-thumbnail

자바스크립트 완벽가이드 10장에 해당하는 부분이고, 읽으면서 자바스크립트에 대해 새롭게 알게된 부분만 정리한 내용입니다.

모듈의 목표는 코드의 세부 사항을 숨기고 다양한 소스에서 가져온 코드가 서로 충돌할 걱정 없이 큰 프로그램으로 모으는 것이다.

클래스, 객체, 클로저를 사용하는 모듈

클래스와 객체를 통한 모듈화는 널리 쓰이고 유용하기도 하지만 그다지 발전되지는 않았다. 무엇보다도 모듈 내부의 세부 사항을 숨길 방법이 없다.

프라이빗 필드와 클로저를 이용한 즉시실행함수 형태로 만들면 가능

즉시 실행함수 형태

const BitSet = (function() {
  // 비공개 세부 사항
  function isValid(set, n) {...}
  function has(set, byte, bit) {...}
  const BITS= new Uint8Array([1, 2, 4, 8, 16, 32, 64, 128]);
  const MASKS = new Uint8Array([~1, ~2, ~4, ~8, ~16, ~32, ~64, ~128]);

  // 모듈의 공개 API
  return class BitSet extends AbstractWritableSet {
    // 생략
  };
})

클로저를 사용하는 모듈화

const modules = {};
function require(moduleName) {return modules[moduleName];}

modules["sets.js"] = (function () {
  const exports = {};

  exports.BitSet = class BitSet{...};

  return exports;
})

modules["stats.js"] = (function () {
  const exports = {};

  const sum = (x, y) => x+ y;
  const square = x => x * x;
  exports.mean = function(data) {...};
  exports.stddev = function(data) {...};

  return exports;
})

노드 프로그램에서 사용하는 require() 함수도 이와 비슷하게 동작한다.

ES6 모듈

일반적인 자바스크립트의 '스크립트'와 중요한 차이가 있다.

일반적인 스크립트에서는 최상위에서 선언한 변수, 함수, 클래스는 모두 모든 스크립트가 공유하는 전역 컨텍스트에 들어간다. 반면, 모듈에서는 각 파일에 비공개 컨텍스트가 잇으며 importexport문을 사용할 수 있다.

웹의 자바스크립트 모듈

<script type="module"> 태그를 지원하는 웹 브라우저는 반드시 <script nomodule> 태그 역시 지원해야 한다. 모듈을 인식하는 브라우저는 nomodule 속성이 있는 스크립트를 모두 무시하고 실행하지 않는다.

지원하지 않는 브라우저는 이를 인식하지 못하고 스크립트를 실행시키므로 이를 통해 브라우저 호환성 문제를 해결할 수 있다.

import()와 동적 가져오기

ES2020에서 import()를 가져오며 동적 가져오기를 지원한다.

import('./stats.js').then(stats => {
  const average = stats.mean(data);
});

async analyzeData(data) {
  const stats = await import('./stats.js');
  return {
    average: stats.mean(data),
    stddev: stats.stddev(data)
  }
}

프라미스형태로 받아오며 그 결과로 import * as를 사용한 것 같은 객체를 반환한다.

import.meta.url

현재 실행 중인 모듈에 관한 메타데이터를 담은 객체를 참조한다.

일반적인 <script>require()로 불러온 노드 모듈에서는 불가능하며, 이 객체의 url 프로퍼티는 모듈을 불러온 URL이다.

URL() 생성자를 사용하면 상대 URL을 import.meta.url 같은 절대 URL을 기준으로 쉽게 해석할 수 있다.

l10n/ 디렉터리에서 파일을 가져오는 경우

function localStringsURL(locale) {
  return new URL(`l10n/${locale}.json`, import.meta.url);
}
profile
It is possible for ordinary people to choose to be extraordinary.

0개의 댓글