웹팩 모듈을 라이브러리로 만들기

웹팩으로 번들링한 모듈은 ES2015의 import , CommonJS의 require() 또는 AMD의 define/require 방식으로 로드할 수 있다. HTML에서 <script>로 로드하려면 webpack.config.jsoutput.libraryoutput.libraryTarget을 설정하면 된다. 이 옵션은 라이브러리 이름과 로드 방식을 설정하는 옵션이다. 이 옵션을 통해 모듈을 라이브러리로 만들 수 있다.

특히, output.libraryTargetumd로 설정하면 모듈은 <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 손찬욱

results matching ""

    No results matching ""