VuePress源碼閱讀(二)--dev和build的執(zhí)行流程分析

006yt1Omgy1gj6rutgcpaj31210la4qp

上篇文章對(duì) VuePress 的源碼進(jìn)行了簡(jiǎn)單分析,了解到:

  • vuepress 包負(fù)責(zé) CLI 命令注冊(cè)及處理八拱,@vuepress 包含著主要的邏輯處理部分
  • 無論是 vuepress dev docs 還是 vuepress build docs 都會(huì)先執(zhí)行 實(shí)例創(chuàng)建createApp 和 解析處理process 兩個(gè)環(huán)節(jié)
  • processs 環(huán)節(jié)可以分為五個(gè)階段阵赠,分別是:
    • 1)配置解析 & 模板加載
    • 2)插件入隊(duì) & 初始化
    • 3)Markdown 相關(guān)處理
    • 4)源文件搜集
    • 5)插件執(zhí)行涯塔,最終生成臨時(shí)文件

但是接下來的階段, vuepress dev docsvuepress build docs 就開始走不通的處理路徑了清蚀。先對(duì)兩個(gè)最主要的執(zhí)行流程進(jìn)行分析有助于我們對(duì)整個(gè)項(xiàng)目有一個(gè)大體的了解匕荸,也有助于之后在此基礎(chǔ)上分析實(shí)現(xiàn)細(xì)節(jié).

一、dev 的執(zhí)行過程

使用過 VuePress 制作網(wǎng)站的同學(xué)應(yīng)該都見過運(yùn)行 vuepress dev docs 的結(jié)果:

image-20210115165436573

前面的 [wds] 表明了 VuePress 的 vuepress dev docs 內(nèi)部就是使用了 webpack-dev-server 的能力來開啟本地服務(wù)器并支持調(diào)試的~

為了驗(yàn)證這一點(diǎn)枷邪,我們來看看 vuepress dev docs 的邏輯:

image-20210115170453911

可以看到通過 createApp 創(chuàng)建實(shí)例榛搔,并且等待資源處理過程 process 執(zhí)行完成之后,開始進(jìn)入 dev 的邏輯了:

image-20210115170620743

進(jìn)入 dev 之后執(zhí)行按下面三個(gè)步驟執(zhí)行:

  • 第一步. 通過 DevProcess類構(gòu)建一個(gè)實(shí)例 devProcess

  • 第二步. 接下來用實(shí)例 devProcess 調(diào)用 process (不同于之前 App 類的 process)

  • 第三步. 最后文件變化監(jiān)聽东揣,并在指定端口啟動(dòng)一個(gè)本地服務(wù)器

第一步可以從構(gòu)造器看出只是單純的上下文賦值践惑,而第二步的 process 就包含了比較多的內(nèi)容了:

image-20210115195207183

其中上面三個(gè) watch 負(fù)責(zé)監(jiān)聽變化,中間的 setupDebugTip 是提供給用戶方便調(diào)試的嘶卧,最后在處理完端口和 host 之后就開始生成 Webpack 配置并放入實(shí)例的 webpackConfig 屬性了.

由上可知尔觉,第二步主要做的是設(shè)置監(jiān)聽 & 構(gòu)建Webpack配置,完成之后就可以進(jìn)入第三步開啟本地服務(wù)器了:

image-20210115202728602

對(duì)于上面的寫法可以參考官網(wǎng)的Demo鏈接:https://www.webpackjs.com/guides/hot-module-replacement/#%E9%80%9A%E8%BF%87-node-js-api

當(dāng)在 NodeJS 中使用 webpack-dev-server 時(shí)芥吟,則應(yīng)該通過 addDevServerEntrypoints(config, options 在代碼中為其寫配置侦铜,第一個(gè)參數(shù)config 即 Webpack 配置专甩,第二個(gè)參數(shù) options 則是我們平常在 webpack.config.js 中寫給 devServer 字段的值對(duì)象. 剩余的編譯和服務(wù)器啟動(dòng)就和官網(wǎng)的Demo基本一致無需贅述了.

到這里使用 vuepress dev docs 的執(zhí)行過程已經(jīng)簡(jiǎn)要地過一遍了:在通用的實(shí)例創(chuàng)建 createApp 和 解析處理process 兩個(gè)環(huán)節(jié)之后進(jìn)入 dev流程,設(shè)置觀察文件變化 & 構(gòu)建 Webpack 配置钉稍,最終通過 webpack-dev-server 啟動(dòng)一個(gè)本地服務(wù)器.

二涤躲、build 的執(zhí)行過程

接下來讓我們繼續(xù)來看看 vuepress build docs 的執(zhí)行過程. 首先我們看看執(zhí)行 vuepress build docs 的結(jié)果:

image-20210115221429580

可以看到在插件流程(app.process)之后,分別發(fā)生了Client 和 Server 兩個(gè)編譯記錄贡未,之后還進(jìn)行了"靜態(tài)HTML渲染"种樱,最終生成靜態(tài)資源到目標(biāo)文件夾中.

之所以Client 和 Server 兩個(gè)編譯記錄,按照基于 SSR 的理解應(yīng)該是:

  • 生成了一份服務(wù)端渲染代碼俊卤,用于生成 HTML

  • 生成了一份對(duì)應(yīng)的客戶端代碼缸托,用于激活服務(wù)端生成的 HTML,使其支持響應(yīng)式

而后面進(jìn)行的"靜態(tài)HTML渲染"瘾蛋,基于 VuePress 通過固定的 markdown 文件生成靜態(tài)網(wǎng)頁(yè)這一特性俐镐,可以理解為由于網(wǎng)頁(yè)全靜態(tài)故無需每次都由服務(wù)器生成,直接打包時(shí)生成一份固定的 "服務(wù)端HTML" 即可.

為驗(yàn)證上面的說法故查看生成結(jié)果哺哼,可以看到左側(cè)的 dist 目錄下都是靜態(tài)的 HTML 文件和資源佩抹,index.html 文件中也包含了 data-server-rendered="true" 這個(gè) SSR 頁(yè)面才具備的特殊屬性,故論證了上面的觀點(diǎn)~

截屏2021-01-15_下午10_26_39

OK 上面從執(zhí)行日志和生成結(jié)果倒推出了如下執(zhí)行過程:

  • 第一步. 編譯服務(wù)端渲染程序 & 客戶端激活程序

  • 第二步. 執(zhí)行服務(wù)端渲染程序 -> 生成服務(wù)端渲染的 HTML

那我們來看看相關(guān)的代碼是怎么樣的取董,我們找到 build 方法的位置(@vuepress/core/lib/node/App.js):

image-20210115223503431

可以看到基于 BuildProcess 創(chuàng)建實(shí)例之后確實(shí)是分成 process 和 render 兩步執(zhí)行的. 由于我們之前看過 dev 的源碼棍苹,所以可以猜測(cè) process 方法應(yīng)該只是用于構(gòu)建 Webpack配置和準(zhǔn)備其他配置,具體執(zhí)行的環(huán)節(jié)應(yīng)該都放在 render 里面了茵汰,接下來我們一個(gè)個(gè)看~

1. process 分析

image-20210115224119530

與 dev 相同的是都是用 resolveCacheLoaderOptions 方法做開始 & 用構(gòu)建 Webpack 配置的 prepareWebpackConfig 方法做結(jié)尾枢里,但是 build 這邊中間少去了一堆監(jiān)聽和調(diào)試處理,只做了結(jié)果目錄創(chuàng)建這一件事情.

2. render 分析

接下來進(jìn)入 render 方法蹂午,簡(jiǎn)單瀏覽發(fā)現(xiàn)每個(gè)階段都有簡(jiǎn)答的注釋栏豺,大致和我們倒推出來的執(zhí)行過程是一致的. 所以接下來以 logger.wait('Rendering static HTML...') 這一行打印為分界線,把程序分成兩部分來看.

1)第一步. 編譯服務(wù)端渲染程序 & 客戶端激活程序

image-20210115231006119

這里我們將 render 方法內(nèi)除了 compile() 之外的代碼都屏蔽掉豆胸,重新運(yùn)行 vuepress build docs 之后奥洼,就可以看到生成了一個(gè)臨時(shí)的 mainfest 文件夾,里面存放著

image-20210115231226335

聯(lián)想一下 Vue SSR 官方的流程圖晚胡,沒錯(cuò)這就是最右邊的上下兩個(gè) Bundle:

786a415a-5fee-11e6-9c11-45a2cfdf085c

接下來就是讀取 bundle, 然后準(zhǔn)備好創(chuàng)建一個(gè) Bundle Render灵奖,以供后續(xù)步驟渲染 HTML 頁(yè)面了(這一部分邏輯中重要部分我都給了序號(hào),沒給序號(hào)的部分可以暫時(shí)忽略):

image-20210115232636231

2)第二步. 執(zhí)行服務(wù)端渲染程序 -> 生成服務(wù)端渲染的 HTML

參考 Vue SSR官網(wǎng) -- Bundle Renderer 指引 這一節(jié)估盘,當(dāng) bundle render 已經(jīng)創(chuàng)建完成瓷患,下一步想要生成靜態(tài)頁(yè)面,肯定就是調(diào)動(dòng) renderToString 函數(shù)了(renderToString 函數(shù)的能力是 自動(dòng)執(zhí)行「由 bundle 創(chuàng)建的應(yīng)用程序?qū)嵗顾鶎?dǎo)出的函數(shù)(傳入上下文作為參數(shù))遣妥,然后渲染它). 現(xiàn)在回到代碼邏輯:

image-20210115233331530

后半部分最終要的其實(shí)就只有 renderPage 的執(zhí)行過程擅编,renderPage 完成渲染后獲得 HTML字符串,最終寫入目標(biāo)文件:

image-20210115233516161

這樣整個(gè) build 的流程就結(jié)束了~

現(xiàn)在我們可以直接進(jìn)入 doc/.vuepress/dist 目錄執(zhí)行 http-server 啟動(dòng)一個(gè)服務(wù)器燥透,查看 build 出來的網(wǎng)頁(yè)喲~

image-20210115233934449

查看請(qǐng)求頁(yè)面沙咏,雖然是用靜態(tài)資源的方式啟動(dòng)的辨图,不過依舊還是 SSR 的形式呢~

image-20210115234001294

小結(jié)

VuePress 的 dev 和 build 兩個(gè)流程前面部分都會(huì)先執(zhí)行 實(shí)例創(chuàng)建createApp 和 解析處理process 兩個(gè)環(huán)節(jié),但是 dev 和 build 后半部分就不太一樣了.

首先他們通過不同的條件判斷獲得不同的 Webpack 配置肢藐,然后:

  • dev 基于 webpack-dev-server 創(chuàng)建本地調(diào)試服務(wù)器

  • build 通過 webpack 讀取 Client故河、Server兩份配置打包出兩個(gè) bundle,再用 bundle render 提前完成 HTML 的生成吆豹,實(shí)現(xiàn)直接生成可用的 SSR HTML 的目的(具備 SEO 優(yōu)化和首屏加載優(yōu)化的特點(diǎn)).

歡迎拍磚鱼的,覺得還行也歡迎點(diǎn)贊收藏~
新開公號(hào):「無夢(mèng)的冒險(xiǎn)譚」歡迎關(guān)注(搜索 Nodreame 也可以~)
旅程正在繼續(xù) ??ヽ(°▽°)ノ?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痘煤,隨后出現(xiàn)的幾起案子凑阶,更是在濱河造成了極大的恐慌,老刑警劉巖衷快,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宙橱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蘸拔,警方通過查閱死者的電腦和手機(jī)师郑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來调窍,“玉大人宝冕,你說我怎么就攤上這事〉巳” “怎么了地梨?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)缔恳。 經(jīng)常有香客問我宝剖,道長(zhǎng),這世上最難降的妖魔是什么褐耳? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任诈闺,我火速辦了婚禮渴庆,結(jié)果婚禮上铃芦,老公的妹妹穿的比我還像新娘。我一直安慰自己襟雷,他們只是感情好刃滓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耸弄,像睡著了一般咧虎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上计呈,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天砰诵,我揣著相機(jī)與錄音征唬,去河邊找鬼。 笑死茁彭,一個(gè)胖子當(dāng)著我的面吹牛总寒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播理肺,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼摄闸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了妹萨?” 一聲冷哼從身側(cè)響起年枕,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乎完,沒想到半個(gè)月后熏兄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡树姨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年霍弹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娃弓。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡典格,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出台丛,到底是詐尸還是另有隱情耍缴,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布挽霉,位于F島的核電站防嗡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏侠坎。R本人自食惡果不足惜蚁趁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望实胸。 院中可真熱鬧他嫡,春花似錦、人聲如沸庐完。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)门躯。三九已至淆党,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背染乌。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工山孔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荷憋。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓饱须,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親台谊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蓉媳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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