[JS] module이 뭐야?

jhj46456·2020년 8월 16일
3

Module

거의 모든 언어에는 module 개념이 있습니다.

대부분 한 파일에 선언된 기능을 다른 파일에 포함시키는 기능을 의미합니다.

이렇게 module을 사용하면서 얻는 주요 이점은 아래와 같습니다.

  • 코드를 최대한 작게 쪼갤 수 있습니다. (함수형 프로그래밍에 유용)
  • 동일한 코드를 여러 앱으로 공유할 수 있습니다. (코드의 재활용)
  • ...

과거

과거에는 JS에 module 개념이 없었습니다. (2009년에 CommonJS가 나오긴 함)

그래서 script 태그를 이용하여 여러 개의 JS 파일을 불러왔습니다.

# index.js
function showMe() {
  return console.log("Hello, I'm Larry");
}

# index.html
<script src="index.js"></script>
<script src="app.js"></script>
...
<script>
  showMe(); // 출력 > Hello, I'm Larry
</script>

이 방법의 경우 종속성 관리를 수동으로 해야합니다.

또한 코드는 위에서 아래로 읽히므로 순서 배치도 중요해집니다.

Module Format

module format은 모듈을 정의하는데 사용합니다.

ES6 이전에는 모듈을 정의하는 공식적인 구문이 없었습니다.

그래서 다양한 format들이 나왔습니다.

  • Asynchronous Module Definition (AMD)
  • CommonJS
  • Universal Module Definition (UMD)
  • System.register

아래는 CommonJS를 사용해본 예제입니다.

# app.js
var obj = {};
obj.show = function() {
  return console.log("I'm Larry.");
}
module.exports = obj

# main.js
require("./larry.js");
require("./larry2.js");
...
console.log(require("app")); // { show: Function }
console.log(require("app").show()) // console > I'm Larry

모듈을 사용하기 위해서는 로더/번들 작업이 필요합니다.

Module Bundler

bundle보따리를 싸다라는 동사입니다. 그 말인 즉슨, 모듈을 보따리로 싸겠다는 뜻입니다.

아래 이미지는 https://webpack.js.org/의 bundle 설명 이미지입니다.

js 뿐만 아니라 css도 가능합니다.

Module BundlerModule Loader를 대체합니다. 그리고 차이점도 있습니다.

  • 컴파일 단계를 도입하여 결과물로 새로운 JS 코드가 생성됩니다.
  • 여러 개의 JS 코드를 하나의 파일로 묶어버리니 종속성 문제가 해결됩니다.
  • 브라우저에서 JS 코드를 한번만 다운로드하면 됩니다.

현재 인기있는 Module Bundler로는 Webpack, Gulp 등이 있습니다.

ES6의 Module

다양한 시행착오를 겪으면서 module formatES6 module format이 추가됩니다.

사용법은 다음과 같습니다.

# one.js
export const show = () => console.log("Hello, I'm Larry");

# two.js
const me = () => console.log("I'm enjoying cooking");
export default me;

# index.js
import { show } from "./one.js";
import two from "./two.js";

show(); // console > Hello, I'm Larry
two(); // console > I'm enjoying cooking

많은 분들이 익숙할 것 같습니다.

👍 코드가 훨씬 깔끔합니다.

📌 하지만 import/export 키워드는 transfile 과정을 거쳐야 사용이 가능합니다.

아래 이미지는 좌측(ES6 모듈), 우측(ES5 변환) 입니다.

transfile 없이 ES6 module 사용하기

📌 권장하는 방법은 아닙니다.

script 태그 안에 type="module" 을 적어주면 됩니다.

# one.js
const name = "Larry";
export const show = () => console.log(name);

# two.js
import { show } from "./two.js";
show();

# index.html
...
<body>
	...
    <script type="module" src="one.js"></script>
    <script type="module" src="two.js"></script>
</body>

결과물은 아래 이미지와 같습니다.

하지만 서버에서 실행하는 것이 아닌 html을 직접 열어보는 경우엔 작동이 안됩니다.

개발환경

앞서 설명드린 requiremodule.exportsCommonJS의 문법입니다.

현재 CommonJS는 Node.js에 기본적으로 탑재가 되어있구요. 이것이 무엇을 뜻할까요?

Node를 이용하여 백엔드를 개발하는 경우 모듈 번들러까지는 필요가 없습니다.

ES6 Module format을 이용하여 코딩했더라도 babel이 require ~ module.exports 구문으로 변환해줍니다.

백엔드 환경에서는 모듈 번들러가 필요없습니다.

그러면 브라우저에서 동적으로 무언가를 동작해야하는 프론트엔드 JS는 어떨까요?

브라우저는 CommonJS를 기본 탑재하고 있지않기 때문에 모듈을 사용하기 위해선 모듈 로더/번들러가 필요합니다.

require() 구문을 이해하지 못합니다.

이런 경우 모듈 로더/번들러를 사용하여 모듈을 불러오거나 파일 하나로 bundle하는 작업이 필요합니다.

프론트 환경에서는 모듈 번들러가 필요합니다.

참조

  • https://www.sitepoint.com/understanding-es6-modules/
  • https://exploringjs.com/es6/ch_modules.html
  • https://www.jvandemo.com/a-10-minute-primer-to-javascript-modules-module-formats-module-loaders-and-module-bundlers/
  • https://arstechnica.com/information-technology/2009/12/commonjs-effort-sets-javascript-on-path-for-world-domination/

0개의 댓글