摘要:類定義了方法,用于注冊(cè)插件,將插件及其回調(diào)函數(shù)以的形式保存在內(nèi)部對(duì)象中又定義了,等方法來(lái)觸發(fā)插件的回調(diào)函數(shù)。所以當(dāng)類繼承類后,也同樣具有注冊(cè)插件和觸發(fā)回調(diào)函數(shù)的功能。
說(shuō)起webpack,相信對(duì)于前端工程師們而言早已經(jīng)不是什么新鮮的事物。但是由于webpack有著較為復(fù)雜和靈活的配置項(xiàng),所以給人的第一感覺(jué)是難以完全掌握。
這次就跟大家分享一下有關(guān)webpack構(gòu)建過(guò)程的相關(guān)知識(shí),希望對(duì)大家進(jìn)一步理解webpack有所幫助。
本次分析的對(duì)象是webpack(v3.6.0),這是gayhub地址 摸我
由于webpack的內(nèi)容實(shí)在太多,一下子講太多東西容易懵逼,我們這次就從最最最簡(jiǎn)單的例子開(kāi)始講起。
以下是我寫(xiě)的一個(gè)炒雞簡(jiǎn)單的例子:
// webpack.config.js var path = require("path"); module.exports = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "build"), filename: "bundle.js" } }
假設(shè)我們的工作目錄下有一個(gè)這樣的webpack.config.js文件,那么當(dāng)我們執(zhí)行webpack命令的時(shí)候【前提是你已經(jīng)安裝了webpack】,那么首先會(huì)執(zhí)行的是 /bin 目錄下的webpack.js
OK,作為入口文件,我們首先要分析的就是: /bin/webpack.js
這個(gè)文件主要做了以下幾件事:
引入yargs模塊,對(duì)命令行參數(shù)進(jìn)行注釋和重命名等工作
添加處理默認(rèn)參數(shù)(比如當(dāng)我們沒(méi)有指定--config參數(shù)的時(shí)候,默認(rèn)去找當(dāng)前目錄下的 webpack.config.js文件作為配置文件)
處理完參數(shù)相關(guān)的內(nèi)容之后,就引入lib目錄下的webpack.js文件,得到編譯對(duì)象compiler,然后進(jìn)行編譯(compiler.run())
var webpack = require("../lib/webpack.js"); ... ... try { // 這里的options就是轉(zhuǎn)換之后的參數(shù),convert-argv文件主要負(fù)責(zé)這些工作 // 得到compiler對(duì)象 compiler = webpack(options); }catch(e) { ... ... } ... ... // 執(zhí)行編譯 compiler.run(compilerCallback)
由于這里講的例子比較簡(jiǎn)單,不涉及到其他參數(shù)相關(guān)的內(nèi)容,感興趣的同學(xué)可以進(jìn)一步了解參數(shù)處理的部分,這里就不多做解釋了。重點(diǎn)我們還是看一下這個(gè)編譯的過(guò)程。
作為complier的入口文件,我們接下來(lái)看一下: /lib/webpack.js
這個(gè)文件首先調(diào)用validateSchema方法對(duì)傳入的options進(jìn)行格式校驗(yàn)
然后又調(diào)用了WebpackOptionsDefaulter實(shí)例的process方法對(duì)options進(jìn)一步的處理(保存了兩個(gè)實(shí)例屬性 default={} , config= {},分別往這兩個(gè)對(duì)象上面掛屬性,然后再掛載到options上)
然后實(shí)例化Compiler類,由于這個(gè)類繼承自Tapable類,所以他具有父類上實(shí)現(xiàn)插件的一套機(jī)制(applyPlugin,plugin等方法,后面會(huì)具體分析這兩個(gè)類),得到compiler對(duì)象
然后執(zhí)行NodeEnvironmentPlugin插件,主要是使用enhanced-resolve模塊修飾compiler對(duì)象,注冊(cè)“before-run”回調(diào)方法
然后調(diào)用complier的apply方法,內(nèi)部其實(shí)調(diào)用插件的apply方法,相當(dāng)于注冊(cè)各種插件的回調(diào)方法
觸發(fā)“environment” 和 “after-environment” 回調(diào)方法
實(shí)例化WebpackOptionsApply類,調(diào)用process方法;后面我們會(huì)展開(kāi)分析這個(gè)方法
往webpack這個(gè)方法上掛一下靜態(tài)屬性(各種插件方法)
導(dǎo)出webpack這個(gè)方法
接下來(lái)我們先分析WebpackOptionsApply類:/lib/WebpackOptionsApply.js
從上面看到,在編譯之前,webpack會(huì)先實(shí)例化WebpackOptionsApply類,然后調(diào)用其process方法
我們看到process方法其實(shí)就是注冊(cè)了N多個(gè)插件,然后觸發(fā)了某些插件的回調(diào)函數(shù)
首先判斷options.target,如果值為“web”的話(這種情況是最常見(jiàn)的,其他情況的邏輯也是類似的),則注冊(cè)插件JsonpTemplatePlugin【注冊(cè)“this-compilation”回調(diào)】,F(xiàn)unctionModulePlugin【注冊(cè)“compilation”回調(diào)】,NodeSourcePlugin【注冊(cè)“compilation” & “after-resolver”回調(diào)】,LoaderTargetPlugin【注冊(cè)“compilation”回調(diào)】。
注冊(cè)插件LibraryTemplatePlugin【注冊(cè)“compilation”回調(diào)】,ExternalsPlugin【注冊(cè)“compile”回調(diào)】
注冊(cè)插件EntryOptionPlugin【注冊(cè)“entry-option”回調(diào)】
觸發(fā)“entry-option”回調(diào),所以進(jìn)入了EntryOptionPlugin插件的回調(diào)函數(shù)
EntryOptionPlugin類中,通過(guò)itemToPlugin方法判斷單入口還是多入口文件,這里以單入口為例,所以進(jìn)入了SingleEntryPlugin類中,注冊(cè)插件SingleEntryPlugin【“compilation” & “make”回調(diào)】
繼續(xù)回到WebpackOptionsApply的process方法,然后又繼續(xù)通過(guò)compile.apply方法添加插件,插件太多了,不一一列舉,感興趣的可以跟蹤代碼了解詳情
最后觸發(fā)“after-plugins” 和 “after-resolvers” 的回調(diào)函數(shù)
以上就是WebpackOptionsApply實(shí)例調(diào)用process的全過(guò)程
在/bin/webpack中,得到的是/lib/webpack返回的compiler對(duì)象,最后調(diào)用compiler對(duì)象的run方法。
作為編譯過(guò)程的核心類,我們接下來(lái)看看Compiler這個(gè)類:/lib/Compiler.js
我們看到Compiler類繼承自Tapable類 github地址
Tapable類提供了一種調(diào)用插件的方式,webpack全部插件都是基于這種方式來(lái)注冊(cè)和調(diào)用的。
Tapable類定義了plugin方法,用于注冊(cè)插件,將插件及其回調(diào)函數(shù)以key-value的形式保存在內(nèi)部_plugins={}對(duì)象中;
又定義了applyPlugins,applyPluginsWaterfall等方法來(lái)觸發(fā)插件的回調(diào)函數(shù)。其實(shí)就是一個(gè)訂閱-發(fā)布模式的實(shí)現(xiàn)。
所以當(dāng)Compiler類繼承Tapable類后,也同樣具有注冊(cè)插件和觸發(fā)回調(diào)函數(shù)的功能。
接下來(lái)看看Compiler中的run方法
首先觸發(fā)的“before-run”回調(diào)函數(shù),NodeEnvironmentPlugin插件注冊(cè)了回調(diào)函數(shù)
然后觸發(fā)“run”回調(diào)函數(shù),CachePlugin插件注冊(cè)了回調(diào)函數(shù)
調(diào)用readRecords方法()
調(diào)用compile方法,進(jìn)入compile過(guò)程
觸發(fā)“before-compile”回調(diào)函數(shù),DllReferencePlugin注冊(cè)了回調(diào)函數(shù)
觸發(fā)“compile”回調(diào)函數(shù),ExternalsPlugin & DllReferencePlugin & DelegatedPlugin注冊(cè)了回調(diào)函數(shù)
調(diào)用newCompilation方法,創(chuàng)建Compilation實(shí)例,這個(gè)實(shí)例包含了編譯過(guò)程的所有屬性和方法
觸發(fā)“this-compilation”回調(diào)函數(shù)
觸發(fā)“compilation”回調(diào)函數(shù)
觸發(fā)“make”回調(diào)函數(shù)
如果是單入口項(xiàng)目,這里就會(huì)觸發(fā)SingleEntryPlugin插件注冊(cè)的“make”回調(diào),其中調(diào)用了compilation的addEntry方法進(jìn)行模塊構(gòu)建
通過(guò)compilation的processModuleDependencies方法收集模塊的依賴
最后通過(guò)buildModule方法構(gòu)建模塊
調(diào)用compilation.finish()方法
調(diào)用compilation.seal()方法
觸發(fā)“after-compile”回調(diào)函數(shù)
compile方法執(zhí)行完之后,就執(zhí)行onCompiled回調(diào)
觸發(fā)“should-emit”回調(diào)函數(shù)
觸發(fā)“done”回調(diào)函數(shù)
調(diào)用emitAssets方法,觸發(fā)了“emit”回調(diào)函數(shù)
調(diào)用emitFiles方法,觸發(fā)“after-emit”回調(diào)函數(shù)
最后執(zhí)行emitRecords方法
這就是compiler的run方法的主要內(nèi)容分析
以上就是webpack簡(jiǎn)單的構(gòu)建流程的分析。哈哈今天就分享到這里,希望大家喜歡,祝大家周末愉快啊。。。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89237.html
摘要:本文相關(guān)代碼已經(jīng)存放在,可自行下載使用多入口復(fù)習(xí)的優(yōu)勢(shì)不言而喻,因此在實(shí)際應(yīng)用中我們也常常使用它調(diào)試多入口應(yīng)用,所謂多入口是指多個(gè)頁(yè)面會(huì)使用多個(gè)入口文件,在官方教程介紹了如何配置這里指定了個(gè)入口文件,打包之后分別會(huì)在文件夾中生成個(gè)打包之后 本文相關(guān)代碼已經(jīng)存放在 dynamic-entry,可自行下載使用 0. 多入口 (復(fù)習(xí)) webpack 的優(yōu)勢(shì)不言而喻,因此在實(shí)際應(yīng)用中我們也常...
摘要:基本配置項(xiàng)基本配置項(xiàng)。的插件架構(gòu)主要基于實(shí)現(xiàn)的,這個(gè)就是專注于事件的廣播和操作。開(kāi)啟多進(jìn)程,加快打包速度。 這次我們主要研究的是webpack框架的相關(guān)知識(shí),webpack是一個(gè)打包構(gòu)建的前端框架,用于解決前端開(kāi)發(fā)的模塊化問(wèn)題。 應(yīng)用場(chǎng)景和縱向比較 說(shuō)到webpack,肯定你還會(huì)想到gulp和grunt這些框架,那么webpack是做什么的呢?他和其他的框架有什么區(qū)別呢?我們一起來(lái)分析...
摘要:不直接使用的原因很簡(jiǎn)單首先構(gòu)建一次實(shí)在太慢了,特別是有幾十個(gè)頁(yè)面存在的情況下,另一個(gè)原因是我只是想拿到資源依賴,我根本不想對(duì)整個(gè)前端進(jìn)行一次構(gòu)建,也不想生成任何。這就達(dá)到了本文題目中目的,用十分之一的構(gòu)建時(shí)間做一場(chǎng)頁(yè)面靜態(tài)資源依賴分析。原文鏈接 作者:梯田 前言: 所謂【靜態(tài)資源依賴分析】,指的是可以通過(guò)分析頁(yè)面資源后,可以以 json 數(shù)據(jù)或者圖表的方式拿到頁(yè)面資源間的依賴關(guān)系。 比如 c...
摘要:為了便于您更清晰的理解的體系架構(gòu),在這里我將為您展示年開(kāi)發(fā)者知識(shí)圖譜,它包含了所有開(kāi)發(fā)過(guò)程中的關(guān)鍵部分。在數(shù)據(jù)展示前端導(dǎo)入導(dǎo)出圖表面板數(shù)據(jù)綁定等場(chǎng)景無(wú)需大量代碼開(kāi)發(fā)和測(cè)試,可極大節(jié)省企業(yè)研發(fā)成本并降低交付風(fēng)險(xiǎn)。 作為 Vue 的初學(xué)者,您或許已經(jīng)聽(tīng)過(guò)很多關(guān)于它的專業(yè)術(shù)語(yǔ)了,例如:?jiǎn)雾?yè)面應(yīng)用程序、異步組件、服務(wù)器端呈現(xiàn)等,您可能還聽(tīng)過(guò)和Vue經(jīng)常一起被提到的工具和庫(kù),如Vuex、Webp...
摘要:由于項(xiàng)目的不斷擴(kuò)大,只會(huì)影響我們定位功能和問(wèn)題的速度,因此對(duì)冗余文件進(jìn)行清理,是很重要的。我們?cè)陧?xiàng)目中使用的,自動(dòng)將各個(gè)圖標(biāo)進(jìn)行。 進(jìn)入公司之后,接手的便是前人留下來(lái)的一個(gè)大項(xiàng)目。慶幸的是整個(gè)項(xiàng)目擁有完善的產(chǎn)品功能文檔,但是由于項(xiàng)目過(guò)于龐大,老舊。包含了打包過(guò)慢,冗余文件過(guò)多等諸多問(wèn)題。想要快速的解決這些問(wèn)題,想要完全把功能重構(gòu)一遍的話,成本太高了。一個(gè)一個(gè)文件來(lái)過(guò),時(shí)間成本也比較大。...
閱讀 2696·2019-08-30 15:55
閱讀 1821·2019-08-30 15:53
閱讀 2674·2019-08-29 18:38
閱讀 940·2019-08-26 13:49
閱讀 512·2019-08-23 15:42
閱讀 3156·2019-08-22 16:33
閱讀 1019·2019-08-21 17:59
閱讀 1094·2019-08-21 17:11