웹팩 모듈을 라이브러리로 만들기
웹팩으로 번들링한 모듈은 ES2015의 import
, CommonJS의 require()
또는 AMD의 define/require
방식으로 로드할 수 있다. HTML에서 <script>
로 로드하려면 webpack.config.js
의 output.library
와 output.libraryTarget
을 설정하면 된다. 이 옵션은 라이브러리 이름과 로드 방식을 설정하는 옵션이다. 이 옵션을 통해 모듈을 라이브러리로 만들 수 있다.
특히, output.libraryTarget
을 umd
로 설정하면 모듈은 <script>
로드 뿐만 아니라 모든 방식의 로더에서 사용할 수 있다. 웹팩 내부 코드를 살펴 보자.
//webpack.config.js
..
output: {
library: "mymodule",
libraryTarget: "umd"
}
..
// dist/mymodule.js
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("mymodule", [], factory);
else if(typeof exports === 'object')
exports["mymodule"] = factory();
else
root["mymodule"] = factory();
})(this, function() {
//what this module returns is what your entry chunk returns
});
webpackUniversalModuleDefinition()
, factory()
는 모듈을 리턴하는 웹팩 내부 함수다. root
즉, this
(실행 컨텍스트)에 라이브러리 이름을 프로퍼티로 추가하고 실제 모듈을 넣는 코드를 볼 수 있다. 이제 HTML에서 <script>
로 mymodule
을 로드할 수 있다.
..
<script src="../dist/mymodule.js"></script>
<script>
// you can use mymodule
</script>
..
이렇게 만든 여러 라이브러리를 하나의 네임스페이스로 묶을 수도 있다. output.library
에 라이브러리 이름을 네임스페이스와 함께 배열 요소로 지정해 주면 된다. mymodule
라이브러리를 myns
네임스페이스에 넣고 싶다면 아래와 같이 한다.
// webpack.config.js
..
output: {
library: ["myns", "mymodule"],
libraryTarget: "umd"
}
..
웹팩 변환 코드는 다음과 같다.
// dist/mymodule.js
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("mymodule", [], factory);
else if(typeof exports === 'object')
exports["mymodule"] = factory();
else
root["myns"] = root["myns"] || {}, root["myns"]["mymodule"] = factory(); // myns가 추가됐다.
})(this, function() {
//what this module returns is what your entry chunk returns
});
실행 컨텍스트에 myns
네임스페이스가 추가됐다. 이제 mymodule
를 사용하기 위해서는 myns.mymodule
로 접근해야 한다.
웹팩을 기반으로 하는 각각 독립적인 컴포넌트가 하나의 네임스페이스로 묶여야 한다면 이 방식이 효율적이다. 여러 컴포넌트가 각각 다른 리파지토리에 있으며 서로 독립적인 컴포넌트라 가정하자. 이 컴포넌트들을 하나의 네임스페이스로 묶는다면 각각 독립적으로 관리하면서 하나의 네임스페이스로 묶어 배포 할 수 있는 장점을 얻을 수 있다.
special thanks to 손찬욱