æä»¶æ¯ webpack çæçå
³é®é¨åï¼
å®ä¸ºç¤¾åºç¨æ·æä¾äºä¸ç§å¼ºæåçæ¹å¼æ¥ç´æ¥è§¦å webpack çç¼è¯è¿ç¨(compilation process)ã
æä»¶è½å¤ hook å°æ¯ä¸ä¸ªç¼è¯(compilation)ä¸ååºçå
³é®äºä»¶ä¸ã
å¨ç¼è¯çæ¯ä¸ªé¶æ®µä¸ï¼æä»¶é½æ¥æå¯¹ compiler 对象çå®å
¨è®¿é®è½åï¼
å¹¶ä¸å¨åéçæ¶æºï¼è¿å¯ä»¥è®¿é®å½åç compilation 对象ã
让æä»¬é¦å ä» tapable å·¥å ·å¼å§ï¼ å®ä¸º webpack æä»¶æ¥å£æä¾äºæ ¸å¿è½åçã
è¿ä¸ªå°ååºæ¯ webpack çä¸ä¸ªæ ¸å¿å·¥å
·ï¼ä½ä¹å¯ç¨äºå
¶ä»å°æ¹ï¼
以æä¾ç±»ä¼¼çæä»¶æ¥å£ã
å¨ webpack ä¸ç许å¤å¯¹è±¡é½æ©å±èª Tapable ç±»ã
å®å¯¹å¤æ´é²äº tapï¼tapAsync å tapPromise çæ¹æ³ï¼
æä»¶å¯ä»¥ä½¿ç¨è¿äºæ¹æ³å webpack 䏿³¨å
¥èªå®ä¹æå»ºçæ¥éª¤ï¼è¿äºæ¥éª¤å°å¨æå»ºè¿ç¨ä¸è§¦åã
请æ¥é
ææ¡£äºè§£æ´å¤ç¥è¯ã
çè§£ä¸é¢ççä¸ç§ tap æ¹æ³ï¼
以åæä¾è¿äºæ¹æ³çé©å(hooks)对äºç¼åæä»¶æ¥è¯´æ¯è³å
³éè¦çã
é£äºæ©å±èª Tapable ç对象ï¼ä¾å¦ï¼compilerï¼ï¼
以åå
¶æä¾çé©å(hooks)åæ¯ä¸ªé©åçç±»åï¼ä¾å¦ï¼åæ¥é©å(SyncHook)ï¼å¼å¾å
³æ³¨ã
æ ¹æ®ä½¿ç¨ä¸åçé©å(hooks)å tap æ¹æ³ï¼
æä»¶å¯ä»¥ä»¥å¤ç§ä¸åçæ¹å¼è¿è¡ã
è¿ä¸ªå·¥ä½æ¹å¼ä¸ Tapable æä¾çé©å(hooks)å¯åç¸å
³ã
compiler hooks åå«è®°å½äº Tapable å
å¨çé©åï¼
å¹¶æåºåªäº tap æ¹æ³å¯ç¨ã
æä»¥ï¼ä¾èµäºä½¿ç¨ç tap æ¹æ³çä¸åï¼
æä»¶å¯è½ä¼ä»¥ä¸åçæ¹å¼è¿è¡ã
ä¾å¦ï¼å½ä½ é©å
¥å° ç¼è¯(compile) é¶æ®µæ¶ï¼åªæåæ¥ç tap æ¹æ³å¯ä»¥ä½¿ç¨ã
compiler.hooks.compile.tap('MyPlugin', (params) => {
console.log('以忥æ¹å¼è§¦å compile é©åã');
});ç¶èï¼å¯¹äºå¯ä»¥ä½¿ç¨ AsyncHook ç run é¶æ®µï¼
åéä½¿ç¨ tapAsync æ tapPromiseï¼ä»¥å tapï¼æ¹æ³ã
compiler.hooks.run.tapAsync(
'MyPlugin',
(source, target, routesList, callback) => {
console.log('以弿¥æ¹å¼è§¦åè¿è¡é©åã');
callback();
}
);
compiler.hooks.run.tapPromise('MyPlugin', (source, target, routesList) => {
return new Promise((resolve) => setTimeout(resolve, 1000)).then(() => {
console.log('以弿¥çæ¹å¼è§¦åå
·æå»¶è¿æä½çé©åã');
});
});
compiler.hooks.run.tapPromise(
'MyPlugin',
async (source, target, routesList) => {
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log('以弿¥çæ¹å¼è§¦åå
·æå»¶è¿æä½çé©åã');
}
);è¿äºéæ±(story)çå«ä¹å¨äºï¼ æä»¬å¯ä»¥æå¤ç§æ¹å¼ hook å° compiler ä¸ï¼å¯ä»¥è®©åç§æä»¶é½ä»¥åéçæ¹å¼å»è¿è¡ã
为äºä¾¿äºå
¶ä»æä»¶çç¼è¯è¿ç¨ä¸å¯ä»¥ tap å°ï¼
ä½ å¯ä»¥è¿æ ·åï¼
Create a module-scope WeakMap for compilation hooks:
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 ææ¡£ æ¥äºè§£æ´å¤ä¸åçé©åç±»(hook class)ï¼ä»¥åå®ä»¬æ¯å¦ä½å·¥ä½çã
æä»¶è½å¤éè¿ ProgressPlugin è¿ä¸ªå¨é»è®¤æ
åµä¸å°ä¿¡æ¯æå°å°æ åé误è¾åº(stderr)çæä»¶æ¥è¿è¡è¿åº¦æ¥åã妿æ³è¦ä½¿ç¨è¿ä¸ªåè½ï¼åªéè¦å¨ä½¿ç¨ webpack CLI çæ¶åä¼ å
¥ --progress åæ°ã
妿æ³è¦èªå®ä¹æå°è¾åºï¼åªéè¦ä¼ éä¸åçåæ°å° ProgressPlugin ç reportProgress æ¹æ³ã
妿æ³è¦æ¥åè¿åº¦ï¼æä»¶å¿
é¡»å¨ tap å° hook çæ¶åä½¿ç¨ context: true é项ã
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 æä»¶ä¼åºäºå½åçé©å(hook)计ç®è¿åº¦ã...argsï¼ä»»ææ°éçå符串ï¼è¿äºå符串ä¼ä¼ éç» ProgressPlugin æä»¶å¹¶æ¥åç»ç¨æ·ã注æï¼åªæ compiler å compilation é©åçåéææ¯æ reportProgress æ¹æ³ã请æ¥ç ProgressPlugin äºè§£æ´å¤ä¿¡æ¯ã
æ¥å¿ç API å¨ webpack 4.37 çæ¬åæä¾æ¯æãå½ logging å¨ ç»è®¡é
ç½®(stats configuration)ä¸å¯ç¨å(æ)å½ infrastructure logging å¯ç¨çæ¶åï¼æä»¶ä¼éè¿åèªçè®°å½æ ¼å¼(statsï¼infrastructure)æå°ä¿¡æ¯ã
compilation.getLogger('PluginName') æ¥åè®°å½ãè¿ç§å½¢å¼çè®°å½ä¿åå¨ç»è®¡æ°æ®(Stats)ä¸å¹¶åç¸åºçæ ¼å¼åãå®è½å¤è¢«ç¨æ·è¿æ»¤å导åºãcompilation.getInfrastructureLogger('PluginName') æ¥åè®°å½ãä½¿ç¨ infrastructure çå½¢å¼å¹¶ä¸ä¼è¢«ä¿åå¨ç»è®¡æ°æ®(Stats)ä¸ï¼å æ¤ä¹ä¸ä¼è¢«æ ¼å¼åãå®éå¸¸ç´æ¥å°è®°å½è½½å
¥å° console/dashboard/GUI ä¸ãå®è½å¤è¢«ç¨æ·è¿æ»¤ãcompilation.getLogger ? compilation.getLogger('PluginName') : console æ¥æ£æµæ¯å¦æ¯æè®°å½ï¼ä»¥æ¤æ¥å¨ä¸æ¯æ compilation.getLogger æ¹æ³çæ§çæ¬ webpack 䏿ä¾éçº§æ¹æ³ãæ¥ç compiler hooks é¨åï¼
äºè§£ææå¯ç¨ç compiler é©å以åå®ä»¬æä¾çåæ°ç详ç»å表ã