ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 플러그인 - 웹팩(Webpack) 기본편 | 김정환
    Front-end/개발환경 2020. 6. 7. 17:59
    반응형

    1. 플러그인의 역할

    웹팩에서 알아야 할 마지막 기본 개념이 플러그인이다. 로더가 파일 단위로 처리하는 반면 플러그인은 번들된 결과물을 처리한다. 번들된 자바스크립트를 난독화 한다거나 특정 텍스트를 추출하는 용도로 사용한다.

     

    이것도 사용하기에 앞서 동작 원리를 이해하기 위해 플러그인을 직접 만들어 보자.

     

    2. 커스텀 플러그인 만들기

    웹팩 문서의 Writing a plugin을 보면 클래스로 플러그인을 정의 하도록 한다. 헬로월드 코드를 가져다 그대로 실행 붙여보자.

     

    my-webpack-plugin.js : 

    class MyWebpackPlugin {
      apply(compiler) {
        compiler.hooks.done.tap('My Plugin', stats => {
          console.log('MyPlugin: done');
        })
      }
    }
    
    module.exports = MyPlugin;

    로더와 다르게 플러그인은 클래스로 제작한다. apply 함수를 구현하면 되는데 이 코드에서는 인자로 받은 compiler 객체 안에 있는 tap() 함수를 사용하는 코드다. 플러그인 작업이 완료되는(done) 시점에 로그를 찍는 코드인것 같다.

     

    플러그인을 웹팩 설정에 추가한다.

     

    webpack.config.js :

    const MyPlugin = require('./myplugin');
    
    module.exports = {
      plugins: [
        new MyPlugin(),
      ]
    }

    웹팩 설정 객체의 plugins 배열에 설정한다. 클래스로 제공되는 플러그인의 생성자 함수를 실행해서 넘기는 방식이다.

     

    웹팩으로 빌드해 보자.

    로그가 찍힌걸 보니 플러그인이 동작했다.

     

    그런데 파일이 여러 개인데 로그는 한 번만 찍혔다. 모듈이 파일 하나 혹은 여러 개에 대해 동작하는 반면 플러그인은 하나로 번들링된 결과물을 대상으로 동작 한다. 우리 예제에서는 main.js로 결과물이 하나이기 때문에 플러그인이 한 번만 동작한 것이라 추측할 수 있다.

     

    그러면 어떻게 번들 결과에 접근할 수 있을까? 웹팩 내장 플러그인 BannerPlugin 코드를 참고하자.

     

    my-webpack-plugin.js :

    class MyPlugin {
      apply(compiler) {
        // compiler.plugin() 함수로 후처리한다
        compiler.plugin('emit', (compilation, callback) => { 
          const source = compilation.assets['main.js'].source();
          console.log(source);
          callback();
        })
      }
    }

    compiler.plugin() 함수의 두번재 인자 콜백함수는 emit 이벤트가 발생하면 실행되는 녀석인 모양이다. 번들된 결과가 compilation 객체에 들어 있는데 compilation.assets[‘main.js’].source() 함수로 접근할 수 있다. 실행하면 터미널에 번들링된 결과물을 확인할 수 있다.

    이걸 이용해서 번들 결과 상단에 아래와 같은 배너를 추가하는 플러그인으로 만들어 보자.

     

    my-webpack-plugin.js :

    class MyPlugin {
      apply(compiler) {
        compiler.plugin('emit', (compilation, callback) => {
          const source = compilation.assets['main.js'].source();
          compilation.assets['main.js'].source = () => {
            const banner = [
              '/**',
              ' * 이것은 BannerPlugin이 처리한 결과입니다.',
              ' * Build Date: 2019-10-10',
              ' */'
              ''
            ].join('\n');
            return banner + '\n' + source;
          }
     
          callback();
        })
      }
    }

    배너 문자열과 기존 소스 코드를 합친 문자열을 반환하도록, 번들 소스를 얻어오는 함수 source()를 재정의 했다. 

    반응형

    댓글

Luster Sun