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