一餐抢、webpack原理+步驟
模塊函數(shù)是webpack能處理的最小單位现使,對(duì)應(yīng)打包前的一個(gè)文件,具體格式是:function(module)
webpack的工作原理:
webpack為每個(gè)require的資源生成一個(gè)唯一的moduleId旷痕,這樣在打包的時(shí)候碳锈,即使多處引用了某資源,也只會(huì)打包一份欺抗,而不會(huì)重復(fù)打包售碳。最后打包生成的chunkId,作用是在加載的時(shí)候,防止重復(fù)加載的模塊贸人,優(yōu)先取緩存间景。
1、全局注冊(cè)一個(gè)啟動(dòng)函數(shù)window.webpackJsonp(chunkIds艺智,modules倘要,立即執(zhí)行的moduleIds)
2、打包后生成的每個(gè)chunk都是 webpackJsonp([1], [,,,,(function(module, exports, __webpack_require__){...}),,], [58]) 這樣的格式:
第一個(gè)參數(shù)是當(dāng)前chunk的id十拣,以及當(dāng)前chunk依賴的chunkIds封拧,
第二個(gè)參數(shù)是打包到當(dāng)前chunk的模塊函數(shù),所有chunk的第二個(gè)參數(shù)長(zhǎng)度應(yīng)該是一樣的夭问,因?yàn)闉榱朔乐鼓K重復(fù)加載泽西,所以模塊id都是唯一的,比如:某次打包一共有2個(gè)chunk甲喝、15個(gè)module尝苇,模塊0-9打包到chunk0下铛只,則chunk0的第二個(gè)參數(shù)的0-9都是模塊函數(shù)對(duì)象埠胖,而chunk1的第二個(gè)參數(shù)的0-9則是空,其10-14又是具體的模塊函數(shù)對(duì)象
第三個(gè)參數(shù)是當(dāng)前chunk加載完成后 立即執(zhí)行的模塊id淳玩,一般入口chunk都是有第三個(gè)參數(shù)的直撤。
3、全局webpackJsonp執(zhí)行的過程中蜕着,會(huì)記錄下已經(jīng)加載過得chunk和模塊以及所有的模塊函數(shù)對(duì)象谋竖,分別保存在installedChunk、installedModule和modules對(duì)象中承匣,每次訪問某個(gè)chunk或者模塊時(shí)蓖乘,優(yōu)先讀取緩存,提高性能韧骗。
4嘉抒、__webpack_require__函數(shù)是用于讀取模塊的。
webpack具體的打包流程是:
1袍暴、利用optimist整合webpack.config.js和命令行中的所有參數(shù)些侍,生成options對(duì)象,傳入webpack webpack啟動(dòng)政模,執(zhí)行run函數(shù)
2岗宣、生成compiler編譯對(duì)象:主要完成模塊的構(gòu)建,包括依賴模塊的構(gòu)建(AST依賴抽象樹)淋样,中間結(jié)合各種loaders\plugins來進(jìn)行處理不同的資源耗式,統(tǒng)一轉(zhuǎn)化成js模塊
3、構(gòu)建完成后,根據(jù)配置進(jìn)行代碼分割刊咳、提取措嵌、封裝
4、利用不同的模板:主入口模板mainTemplate芦缰、非入口模板chunkTemplate生成編譯打包后的文件(mainTemplate與chunkTemplate的區(qū)別在于帶不帶啟動(dòng)代碼)
5企巢、最后完成文件的輸出
webpack源碼分析---后續(xù)總結(jié)
webpack啟動(dòng)后,創(chuàng)建compiler對(duì)象让蕾,開始compile浪规,主要包含下面的幾步:
1、make -> build:(建立模塊探孝,loader處理笋婿,分析依賴)分析配置的主入口,生成模塊對(duì)象顿颅,調(diào)用loaders處理成js模塊缸濒,構(gòu)建AST抽象樹,分析模塊的依賴數(shù)組
2粱腻、seal:(封裝結(jié)果)封裝 根據(jù)模塊依賴關(guān)系+配置(如提取公共模塊)等庇配,將所有的modules對(duì)象進(jìn)行封裝,module分配進(jìn)不同的chunk中绍些;并輸出webpack模塊加載器(一段代碼:注冊(cè)webpackJsonp)
3捞慌、emit:(輸出文件)輸出 將最終的chunk文件輸出到配置好的輸出路徑下。根據(jù)chunk類型的不同柬批,使用不同的模板生成最終的chunkjs
參考:
細(xì)說 webpack 之流程篇---淘寶前端團(tuán)隊(duì)
這篇文章講了webpack的原理 其中manifest講的比較清晰
webpack熱更新原理(websocket貌似過時(shí)了):
1氨距、利用html5的websocket協(xié)議空厌,在客戶端和服務(wù)器端建立起一個(gè)長(zhǎng)鏈接德撬,當(dāng)服務(wù)器端檢測(cè)到文件變化時(shí)扎阶,主動(dòng)向?yàn)g覽器端發(fā)起一個(gè)更新的消息,瀏覽器收到消息上沐,判斷是css更新還是js皮服、html更新以進(jìn)行局部更新或者全局更新,從而減少開發(fā)者手動(dòng)刷新瀏覽器的繁瑣奄容。
【參考】
2冰更、EventSource 是 HTML5 中 Server-sent Events 規(guī)范的一種技術(shù)實(shí)現(xiàn)。EventSource 接口用于接收服務(wù)器發(fā)送的事件昂勒。它通過HTTP連接到一個(gè)服務(wù)器蜀细,以text/event-stream 格式接收事件, 不關(guān)閉連接。通過 EventSource 服務(wù)端可以主動(dòng)給客戶端發(fā)現(xiàn)消息戈盈,使用的是 HTTP協(xié)議奠衔,單項(xiàng)通信谆刨,只能服務(wù)器向?yàn)g覽器發(fā)送; 與 WebSocket 相比輕量归斤,使用簡(jiǎn)單痊夭,支持?jǐn)嗑€重連。
【參考】
loader的原理:
將各種不同類型的資源最終都整合成js模塊脏里,以便webpack處理她我。
二、React的背景+原理:
傳統(tǒng)的web開發(fā)是從服務(wù)器接收到數(shù)據(jù)迫横,然后進(jìn)行dom的更新番舆,比如之前的jQuery方式,每次數(shù)據(jù)的更新矾踱,都需要獲取到dom元素恨狈,進(jìn)行相應(yīng)的增刪改操作。這種方式在頻繁的數(shù)據(jù)刷新下會(huì)導(dǎo)致性能問題呛讲,體驗(yàn)很差禾怠。React的產(chǎn)生極大的解決了這個(gè)問題,它采用了虛擬dom算法贝搁,初次渲染生成一顆虛擬dom樹吗氏,每次收到新數(shù)據(jù)render前,將新數(shù)據(jù)下的dom樹和之前的dom樹進(jìn)行對(duì)比徘公,只將發(fā)生變化的部分進(jìn)行dom更新牲证,而且會(huì)將臨近的幾次dom更新進(jìn)行合并處理哮针,極大的避免了頻繁的dom更新導(dǎo)致的性能問題关面。
具體的dom diff算法關(guān)鍵點(diǎn)有:
- 對(duì)dom樹只進(jìn)行同層的比較,秉承不同類型肯定是不同元素的原則十厢,只要類型不同即替換整棵樹等太,后續(xù)的子節(jié)點(diǎn)不再進(jìn)行比較,降低算法復(fù)雜度蛮放;
- 對(duì)于列表節(jié)點(diǎn)缩抡,使用key屬性,在每次渲染更新的時(shí)候包颁,可以最大限度的進(jìn)行dom元素復(fù)用瞻想;
三、redux相關(guān)
react等組件里面娩嚼,都是以state蘑险、props等進(jìn)行數(shù)據(jù)的存儲(chǔ)和傳遞的,要想讓幾個(gè)組件共享數(shù)據(jù)岳悟,就只能在父級(jí)組件的state內(nèi)存儲(chǔ)數(shù)據(jù)佃迄,一級(jí)一級(jí)的向子組件傳遞泼差。當(dāng)項(xiàng)目很大、組件很多時(shí)呵俏,一級(jí)一級(jí)的傳遞就顯得很繁瑣堆缘。redux解決了這個(gè)問題,可以把redux理解成一個(gè)狀態(tài)機(jī)普碎,是最頂層父級(jí)組件里的state吼肥,通過一些機(jī)制,可以直接通過mapStateToProps麻车、connect將頂級(jí)state直接作為props傳遞給需要的組件潜沦。其中相關(guān)的概念有reducer同步改變數(shù)據(jù)、effect異步改變數(shù)據(jù)绪氛、action發(fā)起請(qǐng)求唆鸡、dispatch等。
四枣察、react router原理
底層利用history模塊實(shí)現(xiàn)争占。具體如何做到url與UI保持一致的:history監(jiān)測(cè)到url的變化,發(fā)起ajax獲取對(duì)應(yīng)的component序目,實(shí)現(xiàn)UI的更新臂痕,同時(shí)進(jìn)行url的替換,具體的底層是調(diào)用history.pushState猿涨、popState握童、replaceState等api實(shí)現(xiàn)瀏覽器前進(jìn)、回退的叛赚。
【參考】