呃,終於到了這地方…… MMP,有31個函數,估計可以寫到明年了。 這裡先梳理所有事件的註入來源,經檢測,全部來源於WebpackOptionsApply中,回到那個可怕的模塊,梳理後如下: 還好都集中在一個地方,這樣又可以寫流水賬了。 這裡先要過一個地方,之前似乎遺留了: 這裡註入了entry-o ...
呃,終於到了這地方……
newCompilation(params) { // ... this.applyPlugins("this-compilation", compilation, params); // 31 console.log(this._plugins['compilation'].length); this.applyPlugins("compilation", compilation, params); return compilation; }
MMP,有31個函數,估計可以寫到明年了。
這裡先梳理所有事件的註入來源,經檢測,全部來源於WebpackOptionsApply中,回到那個可怕的模塊,梳理後如下:
class WebpackOptionsApply extends OptionsApply { constructor() { super(); } process(options, compiler) { // ... if (typeof options.target === "string") { // ... switch (options.target) { case "web": JsonpTemplatePlugin = require("./JsonpTemplatePlugin"); NodeSourcePlugin = require("./node/NodeSourcePlugin"); compiler.apply( new JsonpTemplatePlugin(options.output), // plugin + 3 new FunctionModulePlugin(options.output), new NodeSourcePlugin(options.node), new LoaderTargetPlugin(options.target) ); break; // ... } } // ... // plugin + 1 compiler.apply(new EntryOptionPlugin()); compiler.applyPluginsBailResult("entry-option", options.context, options.entry); // plugin + 24 compiler.apply( /**/ ); compiler.apply( /**/ ); // ... // plugin + 1 compiler.apply(new TemplatedPathPlugin()); // plugin + 1 compiler.apply(new RecordIdsPlugin()); // plugin + 1 compiler.apply(new WarnCaseSensitiveModulesPlugin()); // ... return options; } }
還好都集中在一個地方,這樣又可以寫流水賬了。
這裡先要過一個地方,之前似乎遺留了:
compiler.apply(new EntryOptionPlugin()); compiler.applyPluginsBailResult("entry-option", options.context, options.entry);
這裡註入了entry-option事件流,併在下一行代碼觸發,所以直接進去看實現:
function itemToPlugin(context, item, name) { if (Array.isArray(item)) { return new MultiEntryPlugin(context, item, name); } return new SingleEntryPlugin(context, item, name); } module.exports = class EntryOptionPlugin { apply(compiler) { // context => options.context // entry => options.entry compiler.plugin("entry-option", (context, entry) => { // 針對單字元串或數組情況 if (typeof entry === "string" || Array.isArray(entry)) { // 輸出文件為main compiler.apply(itemToPlugin(context, entry, "main")); } // 對象 => 多入口 else if (typeof entry === "object") { Object.keys(entry).forEach(name => compiler.apply(itemToPlugin(context, entry[name], name))); } // 函數 else if (typeof entry === "function") { compiler.apply(new DynamicEntryPlugin(context, entry)); } return true; }); } };
這裡針對字元串、數組、對象、函數四種情況分別做了處理,先只看單字元串,其餘情況後面單獨講解。
單字元串會進入SingleEntryPlugin插件:
"use strict"; const SingleEntryDependency = require("./dependencies/SingleEntryDependency"); class SingleEntryPlugin { constructor(context, entry, name) { this.context = context; this.entry = entry; this.name = name; }; apply(compiler) { compiler.plugin("compilation", (compilation, params) => { /**/ }); compiler.plugin("make", (compilation, callback) => { /**/ }); }; static createDependency(entry, name) { // 該模塊有一個isEqualResource方法判斷entry是否一樣 const dep = new SingleEntryDependency(entry); dep.loc = name; return dep; } }
這裡引入的SingleEntryDependency原型鏈比較長,而且沒有什麼營養,出一個示意圖,不貼源碼了:
可以看到該模塊註入了兩個事件流,靜態方法後面再講。
第一小節先這樣結束吧!