真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

vue-next/runtime-core源碼閱讀指南詳解

寫在前面

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名與空間、雅安服務(wù)器托管、營銷軟件、網(wǎng)站建設(shè)、揚(yáng)中網(wǎng)站維護(hù)、網(wǎng)站推廣。

最近又抽時(shí)間把 vue-next/runtime-core 的源碼陸陸續(xù)續(xù)地看完了,期間整理了很多筆記,但都是碎片化的。本來是想整理一下,寫成一篇文章分享出來的,但是感覺最終的成果物只能是一篇篇幅巨長的解析文,就算我一行一行的把源碼加上注釋,其閱讀體驗(yàn)也會(huì)很差,因?yàn)槊總€(gè)人讀代碼的習(xí)慣不同,思路不同。正所謂拋磚引玉,所以,我覺的寫一篇向?qū)淖鳛檫@塊磚應(yīng)該是足夠了,希望可以幫助到想看源碼但覺得無從看起、無從下手的讀者。

另一方面,也算是給自己挖一個(gè)坑,因?yàn)檫@篇文章中涉及到的很多內(nèi)容,三言兩語肯定是說不清的,這就意味著之后必須要寫其他文章來填補(bǔ)這些空白。我會(huì)盡可能的將高內(nèi)聚的模塊整理到一起,然后再分享出來,盡量避免陷入羅列代碼的境地,從而提高文章質(zhì)量吧。

閱讀筆記我托管在語雀上,不嫌亂的也可以看這里。

準(zhǔn)備工作

工欲善其事,必先利其器,要看源碼,拿寫字板來看肯定是不行的(當(dāng)然也不排除牛人)。你所需要的就是一個(gè)支持代碼跳轉(zhuǎn)的編輯器即可,我用的是 VSCode,當(dāng)然了,如果你用 VIM、Sublime 也是可以的。

另外還需一些儲(chǔ)備知識(shí):

  • 由于是閱讀 vue-next 的代碼,并且是 pre-alpha 的版本,這就要求你對(duì)之前 vue 有一定的了解,如果是第一次接觸,我覺的閱讀源碼的意義也不是很大
  • 需要熟練掌握 debug 的基礎(chǔ)技巧和流程,通過 debug 的方式來看代碼有兩個(gè)好處
    • debug 過程有清晰地調(diào)用棧記錄
    • 各種作用域下的變量一目了然
  • 需要對(duì) typescript 有一定掌握程度,最起碼給知道 interface、enum 等概念

如何閱讀

一般有三種途徑:

  • 直接看
  • 通過單元測(cè)試的可執(zhí)行代碼
  • 自己編寫的可執(zhí)行代碼

這里推薦第二種方式,因?yàn)閱卧獪y(cè)試是官方團(tuán)隊(duì)維護(hù)的,質(zhì)量肯定有保證,二來單元測(cè)試一般都很簡(jiǎn)單,同時(shí)帶有注釋,這有利于我們理解代碼。

由于 vue-next 使用 jest 進(jìn)行單元測(cè)試,在 vscode 中安裝 Jest 插件即可,它支持行內(nèi) debug lens 快捷入口,方便直接對(duì)某條單元測(cè)試進(jìn)行 debug。

不過要注意配置一個(gè)自定義選項(xiàng):

"jest.debugCodeLens.showWhenTestStateIn": [
  "fail",
  "unknown",
  "pass", // 注意這里
]

這里的 "pass" 代表即使單元測(cè)試通過,也會(huì)在上方顯示 debug lens,默認(rèn)情況下,單元測(cè)試用例通過的話,這個(gè) debug lens 標(biāo)識(shí)不會(huì)顯示。

模塊職能歸納

runtime-core 目錄下有多個(gè)文件,我暫且把每個(gè)文件都當(dāng)做一個(gè)子模塊來看待。vue 的代碼質(zhì)量還是挺好的,模塊與模塊之間的耦合性都不是特別高,正因?yàn)槿绱?,基本上每個(gè)模塊都有自己?jiǎn)为?dú)對(duì)應(yīng)的單元測(cè)試文件。

我在看的時(shí)候,基本上就是挨個(gè)看這些模塊的單元測(cè)試,然后調(diào)試過程中,會(huì)主動(dòng)的進(jìn)行一些代碼跳轉(zhuǎn),去看一下具體的實(shí)現(xiàn)細(xì)節(jié)。下面把當(dāng)前最新代碼下該文件目錄下的所有模塊的職能進(jìn)行一些總結(jié)和歸納。

有一些較獨(dú)立的模塊我還沒有看完,但是不影響整體的源碼閱讀進(jìn)程,日后對(duì)這些獨(dú)立模塊進(jìn)行單獨(dú)研究時(shí),才回來補(bǔ)充這些 todo 就好了。

公共 api 相關(guān)

實(shí)現(xiàn)公共 api 的模塊均是以 apixxx 這樣的格式來命名的,如下:

  • apiApp.ts: 有 3 個(gè)比較重要的接口需要看一下,App、AppConfig 和 AppContext,如果對(duì)于 vue2 比較熟悉的話,會(huì)很容易理解。createApp 是一個(gè)工廠方法,返回一個(gè)符合 App 接口約束的對(duì)象,其內(nèi)部方法會(huì)與一個(gè)符合 AppContext 接口約束的對(duì)象進(jìn)行交互。
  • apiCreateComponent.ts: 這個(gè)文件內(nèi)部包含多個(gè)對(duì)于 createComponent 函數(shù)簽名的重載聲明,其存在目的應(yīng)該是為了幫助 ts 提供更好的類型推斷以提升開發(fā)體驗(yàn)。
  • apiInject.ts: 組件依賴注入 feature 的實(shí)現(xiàn)邏輯,實(shí)現(xiàn)方式很簡(jiǎn)單,直接與 component 文件中暴露的 currentInstance 變量進(jìn)行交互,實(shí)現(xiàn)繼承、賦值、取值等邏輯
  • apiLifecycle.ts: 新的組件聲明周期 hooks,主要看 injectHook 方法就可以了,這里的 target 默認(rèn)情況下指向 currentInstance,之后會(huì)在將某個(gè)回調(diào)邏輯緩存在 currentInstance 實(shí)例的聲明周期回調(diào)函數(shù)數(shù)組中
  • apiOptions.ts:其中包含對(duì)于 component 如何解析 options 的實(shí)現(xiàn)邏輯,代碼比較長同時(shí)也比較復(fù)雜,耦合性與其他幾個(gè)文件較高。但其實(shí)沒有必要直接看完它內(nèi)部的全部代碼,因?yàn)?options 中每一段的解析邏輯互相之間都是獨(dú)立的,因此可以專門針對(duì)某個(gè) option 單獨(dú)去看它內(nèi)部的解析邏輯,我目前只看了 data 以及 lifecycle。
  • apiReactivity.ts:就是對(duì) reactivity 包中的 api 的重新導(dǎo)出,沒有什么額外的東西
  • apiWatch.ts: 暫時(shí)還沒仔細(xì)看,不過根據(jù)名字可知是和 watch 相關(guān)的 api,粗略的看了一下,發(fā)現(xiàn)耦合性比較低,因此可以日后再看

組件相關(guān)

  • component.ts: 主要包含如何創(chuàng)建一個(gè)內(nèi)部組件實(shí)例的邏輯,代碼比較長,但是點(diǎn)進(jìn)去看的話,會(huì)發(fā)現(xiàn)它其實(shí)是在調(diào)用其他模塊的暴露的 api,本身的邏輯還是比較簡(jiǎn)單的。需要注意的是,這個(gè)文件會(huì)暴露一對(duì) setCurrentInstance 和 getCurrentInstance 方法用來維護(hù) currentInstance 變量的指向,同時(shí)它會(huì)在別的模塊中被使用到
  • componentProxy.ts: 聲明了 render proxy 的實(shí)現(xiàn)邏輯,這個(gè) proxy 主要負(fù)責(zé)外部如何與內(nèi)部組件實(shí)例進(jìn)行交互,可以將它看做是一個(gè)外部組件實(shí)例
  • componentProps.ts: 主要看 resolveProps,實(shí)現(xiàn)了如何解析各種形式的 props
  • componentSlots.ts:主要看 resolveChildren,實(shí)現(xiàn)了如何解析各種形式的 children 節(jié)點(diǎn)
  • componentRendererUtils.ts: 一些渲染組件的 util 方法,按名字了解各個(gè)方法的含義即可
  • createRenderer.ts:這個(gè)和其他文件耦合度較低,可以理解為 VNode 的渲染器,只要實(shí)現(xiàn)了其接口,可以在任何上下文環(huán)境中進(jìn)行渲染,比如小程序、native、canvas 或者內(nèi)存環(huán)境,關(guān)于如何編寫一個(gè) renderer,直接看 runtime-test 或者 runtime-dom 的代碼即可
  • directives.ts: 指令相關(guān)的內(nèi)部 api,當(dāng)前的代碼版本,這部分可能很多 todo 因此可以日后再回來看看

其他

  • errorHandling.ts: 錯(cuò)誤處理相關(guān),暫時(shí)還沒仔細(xì)看
  • scheduler.ts: 作業(yè)調(diào)度器相關(guān),暫時(shí)還沒仔細(xì)看
  • shapeFlags.ts: 組件本身和 children 類型的枚舉聲明及常量
  • suspense.ts: suspense 相關(guān),暫時(shí)還沒看,對(duì)于其他文件中的 suspense 的相關(guān)邏輯,我完全是按照 react 中相關(guān)概念來理解的,暫時(shí)沒遇到任何障礙
  • warning.ts: 警告相關(guān),大部分是一些 util 方法,按名字理解其含義就好了

推薦的閱讀順序

直接說我自己的閱讀順序,我認(rèn)為還是比較符合認(rèn)知習(xí)慣的:

  • 先看 vnode.ts 和 h.ts 等關(guān)于 vdom 的代碼了解一下新的 VNode 的數(shù)據(jù)結(jié)構(gòu)
  • 然后再看 apiApp.ts,看掛載過程是怎樣把 VNode 和渲染上下文關(guān)聯(lián)起來的,這個(gè)過程中自然會(huì)涉及到各種 apixxx.ts 中的內(nèi)容,挨個(gè)看就好了
  • 由于之前看的都是公共 api,需要了解實(shí)現(xiàn)細(xì)節(jié)的話,要進(jìn)一步看 component.ts,其中主要包含內(nèi)部組件實(shí)例的數(shù)據(jù)結(jié)構(gòu)以及創(chuàng)建流程,同樣地,打斷點(diǎn)一行一行讀即可
  • 對(duì)于一些解析、工具方法,可以放到最后再看其實(shí)現(xiàn)細(xì)節(jié),打斷點(diǎn)的過程中沒有必要一探到底,因?yàn)橛行┓椒ǖ拿忠呀?jīng)可以很明確的說明其背后實(shí)現(xiàn)的邏輯是什么了

期間會(huì)遇到 suspense、lifecycle 之類的代碼,這類代碼也可以當(dāng)做單獨(dú)的內(nèi)容進(jìn)行閱讀,在一開始看的時(shí)候,也可以不要太糾結(jié)于細(xì)節(jié),當(dāng)對(duì)整體流程有一個(gè)大概了解之后再回頭來看會(huì)清晰很多,之后我會(huì)專門整理一篇文章介紹這塊是如何實(shí)現(xiàn)的。

寫在最后

雖然 vue-next 的代碼現(xiàn)在還處在初期的階段,但是整體的閱讀體驗(yàn)還是不錯(cuò)的,結(jié)構(gòu)清晰,可讀性也比較高,一些關(guān)鍵模塊也有注釋進(jìn)行說明,唯一不足的地方在于,很多地方還是借助 as 關(guān)鍵字來進(jìn)行類型斷言,我覺得這些地方可能有更好的方式實(shí)現(xiàn)類型推斷吧。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。


本文題目:vue-next/runtime-core源碼閱讀指南詳解
本文鏈接:http://weahome.cn/article/ipdhsi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部