Plugin API
플러그인은 webpack 생태계의 핵심 요소이며
커뮤니티에 webpack의 컴파일 프로세스를 활용할 수 있는 강력한 방법을 제공합니다.
플러그인은 각 컴파일 과정에서 발생하는 주요 이벤트에 후킹 할 수 있습니다.
모든 단계에서 플러그인은 컴파일러,
경우에 따라서는 현재 진행 중인 컴파일에 완전한 접근 권한을 가집니다.
먼저 webpack 플러그인 인터페이스의 근간을 제공하는
tapable 유틸리티에 대해 살펴보겠습니다.
Tapable
이 작은 라이브러리는 webpack의 핵심 유틸리티이지만
유사한 플러그인 인터페이스를 제공하기 위해 다른 곳에서도 사용할 수 있습니다.
webpack의 많은 객체가 Tapable 클래스를 확장합니다.
Tapable 클래스가 제공하는 tap, tapAsnyc, tapPromise 메소드를 플러그인에서 사용하여
컴파일 과정에서 실행될 커스텀 빌드 단계를 삽입할 수 있습니다.
자세한 내용은 문서를 참고하세요.
세 가지 tap 메소드와
이를 제공하는 훅을 이해하는 것은 중요합니다.
Tapable을 확장한 객체(예: 컴파일러),
훅, 각 훅의 타입(예: SyncHook)에 대해 알게 될 것입니다.
Plugin Types
사용된 훅과 적용된 tap 메소드에 따라
플러그인은 다양한 방식으로 작동할 수 있습니다.
작동 방식은 Tapable이 제공하는 훅과 밀접한 관련이 있습니다.
컴파일러 훅은 상황에 따라 Tapable 훅을 통해
어떤 tap 메소드가 사용 가능한지 알 수 있습니다.
따라서 어떤 이벤트에 tap 하느냐에 따라 플러그인은 다르게 동작할 수 있습니다.
예를 들어, 컴파일 단계에 후킹 하는 경우
동기식 tap 메소드만 사용할 수 있습니다.
compiler.hooks.compile.tap("MyPlugin", (params) => {
console.log("Synchronously tapping the compile hook.");
});그러나 AsyncHook을 활용하는 run의 경우
tap뿐만 아니라 tapAsync 또는 tapPromise도 사용할 수 있습니다.
compiler.hooks.run.tapAsync(
"MyPlugin",
(source, target, routesList, callback) => {
console.log("Asynchronously tapping the run hook.");
callback();
},
);
compiler.hooks.run.tapPromise("MyPlugin", (source, target, routesList) =>
new Promise((resolve) => {
setTimeout(resolve, 1000);
}).then(() => {
console.log("Asynchronously tapping the run hook with a delay.");
}),
);
compiler.hooks.run.tapPromise(
"MyPlugin",
async (source, target, routesList) => {
await new Promise((resolve) => {
setTimeout(resolve, 1000);
});
console.log("Asynchronously tapping the run hook with a delay.");
},
);즉, 컴파일러에 후킹 하는 다양한 방법이 있으며,
각 방법은 플러그인에 적합하다면 실행될 수 있습니다.
Custom Hooks
다른 플러그인이 tap 할 수 있도록 컴파일에 사용자 정의 훅을 제공하려면,
다음을 수행해야 합니다.
-
컴파일 훅을 위한 모듈 범위
WeakMap을 만듭니다.const compilationHooks = new WeakMap<Compilation, MyHooks>(); interface MyHooks { custom: SyncHook<[number, string]>; } -
플러그인에 정적 메서드를 만듭니다.
static getCompilationHooks(compilation: Compilation) : MyHooks { let hooks = compilationHooks.get(compilation); if(hooks === undefined) { compilationHooks.set(compilation, hooks = { custom: new SyncHook() }); } return hooks; } -
플러그인에서 아래와 같이 훅을 호출합니다.
const hooks = MyPlugin.getCompilationHooks(compilation); hooks.custom.call(1, "hello"); -
다른 플러그인도 사용자 정의 훅에 접근할 수 있습니다.
import MyPlugin from "my-plugin"; const hooks = MyPlugin.getCompilationHooks(compilation); hooks.custom.tap("OtherPlugin", (n, s) => { // magic });
다양한 훅 클래스와 동작 방식에 대해 자세히 알고 싶다면
tapable 문서를 참고하세요.
Reporting Progress
플러그인은 기본적으로 진행 상황을 stderr에 출력하는 ProgressPlugin을 통해 진행 상황을 확인할 수 있습니다. 진행률을 확인하려면 webpack CLI를 실행할 때 --progress 인수를 전달하세요.
ProgressPlugin의 reportProgress 함수에 다른 인수를 전달하여 메시지 출력을 커스텀 할 수 있습니다.
진행 상황을 확인하기 위해서는 context: true 옵션을 사용하여 훅에 tap 해야 합니다.
compiler.hooks.emit.tapAsync(
{
name: "MyPlugin",
context: true,
},
(context, compiler, callback) => {
const reportProgress = context && context.reportProgress;
if (reportProgress) reportProgress(0.95, "Starting work");
setTimeout(() => {
if (reportProgress) reportProgress(0.95, "Done work");
callback();
}, 1000);
},
);reportProgress 함수는 다음과 같은 인수를 사용하여 호출할 수 있습니다.
reportProgress(percentage, ...args);percentage: 이 인수는 사용되지 않습니다. 대신ProgressPlugin이 현재 훅을 기반으로 백분율을 계산합니다....args:ProgressPlugin핸들러로 전달되는 임의의 수의 문자열입니다.
컴파일러 및 컴파일 훅의 하위 집합만이 reportProgress를 지원합니다. 전체 목록은 ProgressPlugin를 참고하세요.
Logging
로깅 API는 webpack 4.37 릴리스부터 사용할 수 있습니다. stats 설정에서 logging이 활성화된 경우 또는 infrastructure logging이 활성화된 경우 플러그인은 각 로거 형식(stats, infrastructure)으로 메시지를 로깅 할 수 있습니다.
- 플러그인은 로깅을 위해
compilation.getLogger('PluginName')를 사용하는 것이 좋습니다. 로그는 형식에 따라 포매팅 되어 Stats에 저장됩니다. 로그는 사용자가 필터링하고 내보낼 수 있습니다. - 플러그인은 로깅을 위해
compiler.getInfrastructureLogger('PluginName')를 사용할 수 있습니다.infrastructure로깅은 Stats에 저장되지 않기 때문에 형식이 지정되지 않습니다. 일반적으로 콘솔 / 대시보드 / GUI에 직접 기록됩니다. 사용자가 필터링 할 수 있습니다. - 플러그인은 로깅 지원 여부를 확인하기 위해 특정한 폴백 로직
compilation.getLogger ? compilation.getLogger('PluginName') : console을 사용하여컴파일객체에서getLogger메소드를 지원하지 않는 이전 webpack 버전이 사용되는 경우에 대한 폴백을 제공 할 수 있습니다.
Next Steps
사용 가능한 모든 컴파일러 훅 및 파라미터에 대한 자세한 목록은
컴파일러 훅 섹션을 참고하세요.

