最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

vue源碼分析學(xué)習(xí)--編譯階段匯總

2023-01-23 11:52 作者:壞蛋Dan丶  | 我要投稿

前言

我們從vue-loader開(kāi)始,一步一步分析到vue/compiler-core包源碼,那么這編譯階段我們就分析完了(這里忽略compiler-ssr) 。

這里涉及到了幾個(gè)包,我們來(lái)整理一下。

文章在知乎上,阿B的文章編輯器是真的那啥。。。。。

https://zhuanlan.zhihu.com/p/600569554


入口

https://zhuanlan.zhihu.com/p/572808664

我這里分析的是基于webpack的,所以入口是vue-loader。

簡(jiǎn)單的說(shuō)下這里面做了什么。

首先在調(diào)用vue-loader之前需要先安裝vueLoaderPlugin

vueLoaderPlugin

這里面主要做了幾件事

  1. vue-loader標(biāo)志位置為true,這樣webpack編譯器就可以調(diào)用vue-loader了。

  2. 復(fù)制一份包含所有loaderrules(不包含vue-loader),分別給它們加上resouceresourceQuery,這倆是用來(lái)確認(rèn)請(qǐng)求的vue資源是否可以被該loader處理的,這里不用擔(dān)心會(huì)影響到其它的loader。

  3. copyrules中注入templateLoader,這樣在資源是vuetemplate的時(shí)候就會(huì)被識(shí)別到并且最終處理成render function。注意render functionjs代碼,所以它也需要被其它loader識(shí)別處理。

  4. 插入css-post-loader用來(lái)處理vuestyle,這里需要注意順序,得在style loadercss loader之前執(zhí)行。

  5. 改寫(xiě)request資源的路徑,這樣才能被vue-loader識(shí)別到。

  6. 覆蓋原來(lái)webpack compilerrules。

然后回到vue-loader中,根據(jù)請(qǐng)求路徑返回對(duì)應(yīng)的資源。這里說(shuō)下script部分沒(méi)有loader,所以在vue-loader識(shí)別到請(qǐng)求的參數(shù)是js的才會(huì)調(diào)用@vue/compiler-sfccompileScript來(lái)處理并返回內(nèi)容。

不同的loader調(diào)用不同的@vue/compiler-sfc方法處理不同的部分:

  • compileTemplate:被templateLoader調(diào)用,用來(lái)處理template部分;

  • compileScript:被vue-loader自身調(diào)用,用來(lái)處理script部分;

  • compileStyle:被css-post-style調(diào)用,用來(lái)處理style部分;

處理完后的資源在vue-loaderruntime拼接之后再傳遞給下一個(gè)loader。

compiler-sfc

那么入口分析完了,就輪到被調(diào)用的包了。

https://zhuanlan.zhihu.com/p/591218245

compileScript

https://zhuanlan.zhihu.com/p/589386136

上面說(shuō)了處理script部分是通過(guò)compileScript這個(gè)方法來(lái)處理的,在這個(gè)文件中核心是調(diào)用babel來(lái)處理js代碼轉(zhuǎn)換為AST節(jié)點(diǎn),然后基于AST?節(jié)點(diǎn)做處理。

場(chǎng)景很多,這里簡(jiǎn)單的說(shuō)下:

  1. 沒(méi)有setup語(yǔ)法糖blockscript,按optionApi的方式來(lái)處理

  2. setup語(yǔ)法糖blockscript且有non setup blockscript,都處理,其中non setup block處理之后整合到setup block的頂部。而setup block處理成非語(yǔ)法糖的寫(xiě)法。

注意:所有的語(yǔ)法糖都只是方便使用,而在編譯階段的都會(huì)轉(zhuǎn)化成原本的寫(xiě)法。

compileTemplate

https://zhuanlan.zhihu.com/p/590240402

這里沒(méi)怎么處理,調(diào)用的是在compiler-dom包里,但是核心處理是在compiler-core里。

compileStyle

https://zhuanlan.zhihu.com/p/591215117

核心是調(diào)用postcss[1]?來(lái)處理。

然后如果有lang的話,調(diào)用對(duì)應(yīng)的預(yù)處理器先。比如lang="scss",那么再開(kāi)始調(diào)用postcss解析之前會(huì)先調(diào)用sass-loader來(lái)處理一遍。

其他沒(méi)什么好說(shuō)的了,但是有個(gè)點(diǎn)這里要提一下,就是處理cssVar。

vue在調(diào)用之前自定義了一個(gè)postcss?插件cssVarsPlugin,這個(gè)插件就是用來(lái)處理vue3.xcss變量的方式。比如color: v-bind(color)會(huì)變成var(--color)的方式。

vue3.x中使用css變量:?SFC CSS Features | Vue.js (vuejs.org)

另外還有一個(gè)點(diǎn),就是scopeId。

每一個(gè)sfc文件都會(huì)有一個(gè)對(duì)應(yīng)的scope Id,如果這個(gè)style block有要求scoped,那么就會(huì)給每個(gè)css rule加上scopeId。

compiler-dom

https://zhuanlan.zhihu.com/p/594633057

你應(yīng)該注意到了,上面compiler-sfc處理完了之后其實(shí)只剩下了template沒(méi)有處理好了,而script、style都已經(jīng)是可以運(yùn)行在瀏覽器中的最終代碼了。

而接下來(lái)compiler-dom以及compiler-core其實(shí)都是在處理template相關(guān)的,因?yàn)?code>template只是一段長(zhǎng)得像htmljs代碼。

不過(guò)尷尬的是html解析引擎不認(rèn)識(shí)它,js的引擎也不認(rèn)識(shí)它。

所以這里就需要自行去把這template處理成js代碼。

compiler-dom這個(gè)包是compiler-core的上游包,也就是基于compiler-core封裝的,加上了一些插件。

這個(gè)包沒(méi)啥好說(shuō)的,感興趣的可以去看下。

不過(guò)這里有幾個(gè)點(diǎn)需要注意:

  1. v-on/v-model等的modifiers也就是修飾符的處理是放到這個(gè)包里的

  2. 過(guò)濾style\script標(biāo)簽也是放在這個(gè)包里,這倆標(biāo)簽不應(yīng)該再出現(xiàn)了(svg標(biāo)簽里的style和這里的不同)

  3. 是否可以staticStringify的判斷和處理都是在這個(gè)包中。

compiler-core

https://zhuanlan.zhihu.com/p/600566832

這個(gè)包是處理template的核心部分

我直接把之前畫(huà)的圖貼出來(lái),應(yīng)該已經(jīng)很清晰了。

img_core_pacakge_work_flow

可以參考babelcore包的架構(gòu)。

簡(jiǎn)單地說(shuō)就是把template這一段字符串通過(guò)parse變成AST,然后通過(guò)transform遍歷所有節(jié)點(diǎn)通過(guò)不同插件處理節(jié)點(diǎn),接著通過(guò)generate生成render function。這個(gè)時(shí)候的render function已經(jīng)是瀏覽器可以執(zhí)行的runtime js代碼了。

優(yōu)化

這里面關(guān)于優(yōu)化的東西我都沒(méi)有分析,這里就簡(jiǎn)單說(shuō)下我遇到過(guò)的優(yōu)化:

  1. cache,這個(gè)cacheruntime的,比如指令的value是一個(gè)表達(dá)式,那么表達(dá)式的結(jié)果其實(shí)是可以緩存的,這樣每次調(diào)用返回緩存即可。而compile階段的緩存更多的是和hot-reload搭配的,在下一次編譯的時(shí)候可以過(guò)濾掉。

  2. staticHoist,這個(gè)我們是有分析的,因?yàn)樵谥髁鞒讨小Mㄟ^(guò)判斷不同的點(diǎn),比如屬性是否是靜態(tài)之類(lèi)的來(lái)判斷這個(gè)節(jié)點(diǎn)是否每次都需要create,如果不需要就把它提升到頂部,這樣就只需要create一次。注意這個(gè)是runtime的優(yōu)化。另外這里可以hoist不只有dom節(jié)點(diǎn),還有屬性節(jié)點(diǎn)等也是可以的。

  3. staticStringify,這個(gè)是在staticHoist的基礎(chǔ)上,如果不滿(mǎn)足hoist的條件那就一定不滿(mǎn)足stringify的條件。stringify使用的是innerHTML的方式插入,所以只有這一塊代碼中節(jié)點(diǎn)數(shù)量/指令數(shù)量達(dá)到了一定的個(gè)數(shù)時(shí)才會(huì)stringify,因?yàn)槿绻麛?shù)量少,其實(shí)innerHTML插入的性能沒(méi)啥提升。

  4. PatchFlag,也就是插旗,給不同類(lèi)型的節(jié)點(diǎn)插旗,這樣可以快速定位需要如何處理,在patch的時(shí)候diff就能繞過(guò)一些邏輯,減少diff的時(shí)間和損耗。

  5. track,實(shí)際上和插旗一樣,跟蹤上面的flag,如果沒(méi)有flag的節(jié)點(diǎn),那diff階段就可以skip了。


總結(jié)

那么編譯階段的源碼我們就都分析完了,這一套分析下來(lái)其實(shí)我個(gè)人學(xué)到的東西非常非常多,整個(gè)vue的編譯流程也比以前清晰的多。


現(xiàn)在也不再覺(jué)得這是魔法了~


最后如果覺(jué)得對(duì)你有幫助的話請(qǐng)務(wù)必點(diǎn)個(gè)贊~


最后的最后,祝大家新春快樂(lè)!!


vue源碼分析學(xué)習(xí)--編譯階段匯總的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
茂名市| 伊宁县| 波密县| 涞水县| 资中县| 沙河市| 杭州市| 徐闻县| 清徐县| 诏安县| 陆丰市| 怀来县| 玉林市| 广西| 迁安市| 双城市| 龙海市| 水城县| 晋江市| 汝州市| 江陵县| 苍梧县| 祁连县| 吐鲁番市| 太原市| 五原县| 太仆寺旗| 锡林浩特市| 大邑县| 南岸区| 钟山县| 隆子县| 双峰县| 全州县| 田阳县| 富宁县| 溆浦县| 石门县| 永泰县| 唐山市| 新津县|