참고자료: https://defineall.tistory.com/916
라이브러리를 배포할 때, 최적화를 위해 모듈로 구성하여 배포하게 된다. 각각 모듈의 특징이 존재하여 맞는 것을 찾아야한다.
프로젝트 목적에 따라 다르지만, 주로 라이브러리를 만들 경우 번들링 도구를 통해 ESM와 UMD(CJS가능)를 동시에 번들하여, 호환성을 최대화하여 사용한다.
리액트네이티브는 Metro 번들러가 ESM을 완전히 지원하지 않기 때문에, UMD(CJS가능)로 모듈화 해야했다.
모두 자바스크립트 모듈 시스템으로 코드를 분할하고 관리하기 위한 방식이다.
모듈 분리 시 장점
javascript를 브라우저에서만 아니라 다른 곳에서도 사용할 수 있게 해주는 API
특징 :
require
와 module.exports
문법을 사용함// require를 통해 모듈을 변수에 담을 수 있게 되었다
var lib = require('package/lib');
// 가져온 모듈을 사용할 수 있게 되었다.
function foo() {
lib.log('hello world!');
}
// foo 함수를 다른 파일에서 사용할 수 있도록, 다른 모듈로 추출할 수 있게 되었다
exports.foobar = foo;
클라이언트 사이드에서 주로 사용, 비동기적으로 작동
define
함수와 콜백을 통해 모듈을 정의// myModule.js
// define을 이용해 새로운 모듈을 불러오고, 콜백함수로 전해줌
define(['package/lib'], function (lib) {
// 콜백함수 이용해서, 불러온 모듈 사용가능
function foo () {
lib.log('hello world!');
}
// 다른파일에서 foo함수를, foobar이란 이름의 모듈로 불러올 수 있게 만듬
return {
foobar: foo
};
});
// 위에서 선언한 모듈 불러오기
require(['package/myModule'], function (myModule) {
myModule.foobar();
});
서버와 클라이언트 양쪽에서 사용될 수 있는 모듈을 개발할 때 사용됩니다. 코드를 한 번 작성하여 여러 환경에서 동작하게 하려는 경우 유용합니다.
특징:
사용법
(function (root, factory) {
if(typeof define === 'function' && define.amd) {
// define이 함수이고, define.amd가 존재할때 AMD사용
define(['exports', 'b'], factory);
} else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
// export가 객체이고, export.nodeName이 문자열이 아닐때, CommonJS사용
factory(exports, require('b'));
} else {
//Browser globals
factory((root.commonJsStrict = {}), root.b);
}
}(this, function (exports, b) {
// use b in some fashion.
// attach properties to the exports object to define
// the
exports.action = function () {};
}));
이 중 가장 최신 모듈 포멧. 동기 비동기를 지원하지만, 호환이 안되는 브라우저가 있을 수도 있어 번들어와 함께 사용된다.
사용법
// import, from 구문을 사용할 수 있다!
import lib from 'package/lib';
function foo () {
lib.log('hello world!');
}
export {
foobar: foo
};
사용법
<html>
<body>
<script type="module" src="foo.mjs"></script>
<script type="module" src="foo.mjs"></script>
</body>
</html>
// foo.mjs
var x = 'foo';
console.log(x); // foo
console.log(window.x);
사용하는 곳
// bar.mjs
// import를 사용해, 모듈을 불러온다
import test from "./module.mjs";
console.log(test);
var x = 'bar';
console.log(x);
console.log(window.x);
CJS와 ESM : https://junghyeonsu.com/posts/deploy-simple-npm-library/
CJS와 ESM에 대응하는 라이브러리 개발하기 : https://toss.tech/article/commonjs-esm-exports-field