웹 패키지 플러그인 메커니즘 찾기
6326 단어 webpack
웹팩 플러그인
먼저 웹 패키지 플러그인의 프로젝트에서의 활용을 살펴보겠습니다.
const MyPlugin = require('myplugin')
const webpack = require('webpack')
webpack({
...,
plugins: [new MyPlugin()]
...,
})
그러면 어떤 조건에 부합되면 웹 패키지 플러그인으로 쓸 수 있을까요?일반적으로 웹 패키지 플러그인은 다음과 같은 특징을 가지고 있다.
다음 코드는 다음과 같습니다.
function MyPlugin(options) {}
// 2. apply compiler
MyPlugin.prototype.apply = function(compiler) {
// 3.compiler webpack 4. compilation
compiler.plugin('emit', (compilation, callback) => {
...
})
}
// 1. JS ,
module.exports = MyPlugin
이렇게 웹 패키지 플러그인의 기본적인 윤곽이 그려졌는데, 이때 의문점은 몇 가지가 있다.
plugin.apply()
플러그인을 호출한 것을 발견했습니다.const webpack = (options, callback) => {
...
for (const plugin of options.plugins) {
plugin.apply(compiler);
}
...
}
이 의문들도 본문의 단서이니 하나씩 탐색해 봅시다.
compiler 객체
compiler는 웹 패키지의 편집기 대상입니다. 웹 패키지를 호출할 때 자동으로 compiler 대상을 초기화합니다. 원본은 다음과 같습니다.
// webpack/lib/webpack.js
const Compiler = require("./Compiler")
const webpack = (options, callback) => {
...
options = new WebpackOptionsDefaulter().process(options) // webpack
let compiler = new Compiler(options.context) // compiler , options.context process.cwd()
compiler.options = options // compiler
new NodeEnvironmentPlugin().apply(compiler) // compiler Node
for (const plugin of options.plugins) {
plugin.apply(compiler);
}
...
}
마지막으로,compiler 대상에는 모든 웹 패키지가 설정할 수 있는 내용이 포함되어 있으며, 플러그인을 개발할 때,compiler 대상에서 웹 패키지의 주 환경과 관련된 모든 내용을 얻을 수 있습니다.
compilation 객체
compilation 대상은 단일한 버전 구축과 자원 생성을 대표합니다.웹 패키지를 실행할 때 파일의 변화가 감지될 때마다 새로운 컴파일러가 생성되어 새로운 컴파일러 자원을 생성합니다.하나의 컴파일 대상은 현재의 모듈 자원, 컴파일 생성 자원, 변화된 파일, 그리고 추적에 의존하는 상태 정보를 나타낸다.
원본과 결합하여 위의 말을 이해하면 먼저 웹팩은 실행할 때마다 호출
compiler.run()
(원본의 위치)를 하고 onCompiled 함수에서 전송된compilation 파라미터를 추적하면compilation이 구조 함수Compilation에서 온 것을 발견할 수 있다.// webpack/lib/Compiler.js
const Compilation = require("./Compilation");
newCompilation(params) {
const compilation = new Compilation(this);
...
return compilation;
}
언급할 수 없는 tapable 라이브러리
compiler 대상과compilation 대상을 다시 소개한 후에는tapable 라이브러리를 언급하지 않을 수 없습니다. 이 라이브러리는 사건과 관련된pub/sub의 모든 방법을 폭로했습니다.또한 함수 Compiler와 함수 Compilation은 Tapable에서 상속됩니다.
이벤트 훅
이벤트 갈고리는 사실 MVVM 프레임워크와 유사한 생명주기 함수로 특정 단계에서 특수한 논리 처리를 할 수 있다.흔히 볼 수 있는 이벤트 갈고리를 이해하는 것은 웹 패키지 플러그인을 쓰는 선행 조건이다. 다음은 흔히 볼 수 있는 이벤트 갈고리와 작용을 열거한다.
갈고리
역할
매개 변수
타입
after-plugins
초기화 플러그인 설정 후
compiler
sync
after-resolvers
Resolvers 설정 후
compiler
sync
run
레코드를 읽기 전에
compiler
async
compile
새 compilation을 만들기 전에
compilationParams
sync
compilation
compilation 생성 완료
compilation
sync
emit
자원을 생성하고 디렉터리로 출력하기 전에
compilation
async
after-emit
자원을 생성하고 디렉터리로 출력한 후
compilation
async
done
컴파일 완료
stats
sync
공식 문서 매뉴얼을 완전하게 참고하고 관련 원본 코드를 찾아보면 각 이벤트 갈고리의 정의를 뚜렷하게 볼 수 있다.
플러그인 프로세스 분석
emit 갈고리를 예로 들면 다음과 같이 플러그인 호출 코드를 분석합니다.
compiler.plugin('emit', (compilation, callback) => {
//
})
여기에서 호출된plugin 함수는 위에서 언급한tapable 라이브러리에서 유래한 것으로, 최종 호출 창고는 hook을 가리킨다.tapAsync () 는 Event Emitter의 on과 유사하며 소스는 다음과 같습니다.
// Tapable.js
options => {
...
if(hook !== undefined) {
const tapOpt = {
name: options.fn.name || "unnamed compat plugin",
stage: options.stage || 0
};
if(options.async)
hook.tapAsync(tapOpt, options.fn); //
else
hook.tap(tapOpt, options.fn);
return true;
}
};
주입은 반드시 촉발하는 곳이 있고 원본에서callAsync 방법을 통해 주입하기 전에 주입한 비동기 이벤트를 촉발한다.callAsync는 Event Emitter의emit와 유사하며 관련 원본은 다음과 같다.
this.hooks.emit.callAsync(compilation, err => {
if (err) return callback(err);
outputPath = compilation.getPath(this.outputPath);
this.outputFileSystem.mkdirp(outputPath, emitFiles);
});
일부 깊이 있는 세부 사항은 여기서 전개하지 않고 비교적 큰 프로젝트의 원본 코드를 읽는 두 가지 체험을 말한다.
웹 패키지 플러그인 만들기
상기 지식점의 분석을 결합하여 자신의 웹 패키지 플러그인을 쓰기 어렵지 않은데 관건은 생각에 있다.프로젝트에서 웹 패키지 각 패키지의 효과적인 사용 상황을 통계하기 위해 fork 웹 패키지-visualizer를 토대로 코드를 업그레이드하여 프로젝트 주소를 지정했습니다.효과는 다음과 같습니다.
플러그인 핵심 코드는 위에서 언급한emit 갈고리와compiler와compilation 대상을 바탕으로 한다.코드는 다음과 같습니다.
class AnalyzeWebpackPlugin {
constructor(opts = { filename: 'analyze.html' }) {
this.opts = opts
}
apply(compiler) {
const self = this
compiler.plugin("emit", function (compilation, callback) {
let stats = compilation.getStats().toJson({ chunkModules: true }) //
let stringifiedStats = JSON.stringify(stats)
//
let html = `
AnalyzeWebpackPlugin
window.stats = ${stringifiedStats};
${jsString}
`
compilation.assets[`${self.opts.filename}`] = { //
source: () => html,
size: () => html.length
}
callback()
})
}
}
참고 자료
진짜 Webpack 플러그인 잘 보세요.
웹팩 홈페이지
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Qiita API v2를 Ajax에서 사용하기위한 webpack 설정 (로컬 개발 환경 전용)에서는 Qiita의 기사 목록, 사용자 세부 정보, 기사를 '좋아요'한 사람 목록 및 재고가 있는 사람 목록을 검색할 수 있습니다. Qiita 화면에서 기사를 재고한 사람을 볼 수 없기 때문에 API를 통해 기사를 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.