探索webpack源碼(五) Compiler.js(下) 2018-05-04

0x03 readRecords方法

上一次我們剛剛看完為什么要用tapable把beforeRun與run的callAsync調(diào)用的 "骨架" 先寫好,這次我們就繼續(xù)往下看吧备图。

this.hooks.run.callAsync(this, err => {
    if (err) return callback(err);

    this.readRecords(err => {
        if (err) return callback(err);

        this.compile(onCompiled);
    });
});

這里就是run節(jié)點(diǎn)調(diào)用完了以后執(zhí)行的回調(diào)代碼拖叙,首先就調(diào)用了 this.readRecords

readRecords(callback) { 
  if (!this.recordsInputPath) {
    this.records = {};
    return callback();
  }
  // something code...
}

在compiler.js可以直接找到這個(gè)函數(shù)眷昆,這里要回顧以下之前說的重點(diǎn),這次是重點(diǎn)探索在命令行輸入 "webpack" 之后的代碼,但是單純輸入 "webpack" 卻直接在if里被干掉了失受,下面的代碼沒有繼續(xù)讶泰,目前猜可能是其他js里面會用到,例如watch拂到?(瞎猜一下)

執(zhí)行了if痪署,return并執(zhí)行了callback,就進(jìn)入了剛剛的this.readRecords的回調(diào)兄旬,執(zhí)行編譯的方法:

this.compile(onCompiled)

0x04 compile方法

接下來看 compile 方法

compile(callback) {
  const params = this.newCompilationParams();
  // something code...
}

首先狼犯,執(zhí)行了 compile 進(jìn)行編譯,編譯的話就需要一個(gè)編譯環(huán)境领铐,那么自然就會有一個(gè)對應(yīng)的 compilation悯森。

所以第一行就初始化了編譯環(huán)境的參數(shù) compilation params

0x05 newCompilationParams方法

可以在當(dāng)前的js追溯一下這個(gè)方法:

newCompilationParams() {
    const params = {
        normalModuleFactory: this.createNormalModuleFactory(),
        contextModuleFactory: this.createContextModuleFactory(),
        compilationDependencies: new Set()
    };
    return params;
}

這里的參數(shù)有三個(gè)绪撵,創(chuàng)建完就返回出去待用瓢姻,但是暫時(shí)還沒發(fā)現(xiàn)用處,可能下一波 compilation.js 探索時(shí)能發(fā)現(xiàn)音诈。
normalModuleFactory:普通模塊工廠
contextModuleFactory:上下文模塊工廠
compilationDependencies:編譯環(huán)境的依賴項(xiàng)

0x06 beforeCompile與compile鉤子幻碱。

好的,之前是在webpack調(diào)用了compiler.run函數(shù)细溅,然后執(zhí)行run鉤子∪彀現(xiàn)在在run鉤子中調(diào)用compiler.compile函數(shù),所以現(xiàn)在就開始執(zhí)行compile的鉤子了喇聊。

this.hooks.beforeCompile.callAsync(params, err => {
  if (err) return callback(err);
  this.hooks.compile.call(params);
  // something code ...
})

這里就是接著剛剛 newCompilationParams 創(chuàng)建參數(shù)之后的代碼恍风。

這里有倆鉤子,一個(gè)編譯前承疲,一個(gè)編譯中的鉤子邻耕。之前怎么讀這里的講的很詳細(xì),相信把屬性點(diǎn)加到智力上的同學(xué)都能看懂燕鸽,我就不細(xì)說了兄世,只提示要注意的地方。

所以這里要注意的有兩點(diǎn):

1啊研、compile 的鉤子御滩,這里主要就是tap了三個(gè)插件, DelegatedPlugin党远、DllReferencePlugin削解、ExternalsPlugin,分別的 委派插件沟娱、DLL渲染插件氛驮、擴(kuò)展插件,這里有疑問是好是济似,但是我暫時(shí)也不知道他們是干嘛的(逃

2矫废、而 beforeCompile 的鉤子似乎只有兩個(gè)地方綁定盏缤,一個(gè)只是報(bào)消息:

compiler.hooks.beforeCompile.tap("WebpackInfo", compilation => {
  console.log("\nCompilation starting…\n");
});

相信大家都看過。

而另一個(gè)應(yīng)該是用于處理剛剛 newCompilationParams 創(chuàng)建的params蓖扑,因?yàn)槲铱吹剿袑?compilation.dependencies 做處理唉铜,詳情在 DllReferencePlugin.js 文件,全局搜索 beforeCompile.tap 即可律杠。

0x07 newCompilation

接下來就是創(chuàng)建編譯環(huán)境了

const compilation = this.newCompilation(params);

這一段主要是 compilation.js 的內(nèi)容潭流,我這里只粗略的介紹一下。

newCompilation(params) {
    const compilation = this.createCompilation();
    compilation.fileTimestamps = this.fileTimestamps;
    compilation.contextTimestamps = this.contextTimestamps;
    compilation.name = this.name;
    compilation.records = this.records;
    compilation.compilationDependencies = params.compilationDependencies;
    this.hooks.thisCompilation.call(compilation, params);
    this.hooks.compilation.call(compilation, params);
    return compilation;
}

放眼一看柜去,主要就是創(chuàng)建了一個(gè) compilation 實(shí)例對象灰嫉,然后對它進(jìn)行各種配置,并且執(zhí)行了它的倆鉤子诡蜓,分別是 thisCompilation 與 compilation熬甫。

也就是編譯環(huán)境 開始之前正在進(jìn)行時(shí) 的鉤子。

最后返回創(chuàng)建好的編譯環(huán)境實(shí)例蔓罚。

0x08 make鉤子

創(chuàng)建完 compilation 編譯環(huán)境后椿肩,就要開始構(gòu)建了,

this.hooks.make.callAsync(compilation, err => {
  if (err) return callback(err);
  compilation.finish();
  // something code ...
});

make 負(fù)責(zé)構(gòu)建webpack各模塊之間的內(nèi)容豺谈,看到把 compilation 當(dāng)作參數(shù)傳入就知道什么原因了郑象,就是要開始操作編譯環(huán)境了。

0x09 構(gòu)建完成與封裝構(gòu)建

上面已經(jīng)經(jīng)過make構(gòu)建了茬末,現(xiàn)在是操作構(gòu)建完成后的事情厂榛。

// 編譯完成,關(guān)閉編譯環(huán)境
compilation.finish();

// 封裝編譯構(gòu)建的結(jié)果丽惭。
compilation.seal(err => {
  if (err) return callback(err);
  // something code...
});

0x0A afterCompile編譯完成后鉤子

接著就是封裝完成后的鉤子 afterCompile 鉤子击奶。

this.hooks.afterCompile.callAsync(compilation, err => {
  if (err) return callback(err);
  return callback(null, compilation);
})

這里也是如題所示,最后就是執(zhí)行callback了责掏。

這個(gè) callback 不知道有沒被大家遺忘啊柜砾,不過相信大部分玩家都有印象。

就是執(zhí)行最初 compiler.compile(onCompiled) 時(shí)傳的callback onCompiled 换衬。

0x0B run函數(shù)中的callback onCompiled

又回到最初的起點(diǎn)痰驱,最后一點(diǎn)了,直入正題吧瞳浦。

const onCompiled = (err, compilation) => {
  if (err) return callback(err);
  // something code ...
  this.emitAssets(compilation, err => {
    if (err) return callback(err);
    // something code ...
    this.emitRecords(err => {
      if (err) return callback(err);
      // something code ...
      this.hooks.done.callAsync(stats, err => {
        if (err) return callback(err);
        return callback(null, stats);
      });
    });
  });
};

這里一頓鉤子操作担映,把輸出的資源鉤子都羅列出來了。

鉤子 作用
emitAssets 輸出資源
emitRecords 記錄輸出
done 結(jié)束鉤子

當(dāng)然 onCompiled 肯定不止這幾個(gè)鉤子叫潦,但是其他的鉤子在if中蝇完,執(zhí)行的時(shí)候并沒有進(jìn)入判斷,所以先忽略吧。


殺青短蜕,殺青泛源!下一次有可能就是Compilation.js的,請期待哦忿危。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市没龙,隨后出現(xiàn)的幾起案子铺厨,更是在濱河造成了極大的恐慌,老刑警劉巖硬纤,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件解滓,死亡現(xiàn)場離奇詭異,居然都是意外死亡筝家,警方通過查閱死者的電腦和手機(jī)洼裤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溪王,“玉大人腮鞍,你說我怎么就攤上這事∮猓” “怎么了移国?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長道伟。 經(jīng)常有香客問我迹缀,道長,這世上最難降的妖魔是什么蜜徽? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任祝懂,我火速辦了婚禮,結(jié)果婚禮上拘鞋,老公的妹妹穿的比我還像新娘砚蓬。我一直安慰自己,他們只是感情好掐禁,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布怜械。 她就那樣靜靜地躺著,像睡著了一般傅事。 火紅的嫁衣襯著肌膚如雪缕允。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天蹭越,我揣著相機(jī)與錄音障本,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛驾霜,可吹牛的內(nèi)容都是我干的案训。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼粪糙,長吁一口氣:“原來是場噩夢啊……” “哼强霎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蓉冈,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤城舞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后寞酿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體家夺,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年伐弹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拉馋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惨好,死狀恐怖煌茴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情日川,我是刑警寧澤景馁,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站逗鸣,受9級特大地震影響合住,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜撒璧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一透葛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卿樱,春花似錦僚害、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蹄胰,卻和暖如春岳遥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背裕寨。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工浩蓉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留派继,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓捻艳,卻偏偏與公主長得像驾窟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子认轨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容