自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何閱讀源碼 —— 以 Vetur 為例

開發(fā) 前端
這是一個(gè)預(yù)期管理的問題,我們可以多參考 SMART 原則,多從具體、可衡量、可行性、相關(guān)性幾個(gè)維度思考,不斷推敲是否需要做這件事;如何拆解目標(biāo),用目標(biāo)反推計(jì)劃,不斷推進(jìn)個(gè)人成功。

[[414734]]

本文轉(zhuǎn)載自微信公眾號(hào)「Tecvan」,作者范文杰 。轉(zhuǎn)載本文請(qǐng)聯(lián)系Tecvan公眾號(hào)。

我很早就意識(shí)到,能熟練、高效閱讀開源前端框架源碼是成為一個(gè)高級(jí)前端工程師必須具備的基本技能之一,所以在我職業(yè)生涯的最早期,就已經(jīng)開始做了很多次相關(guān)的嘗試,但結(jié)果通常都以失敗告終,原因五花八門:

  • 缺乏必要的背景知識(shí),猶如閱讀天書
  • 不理解項(xiàng)目架構(gòu)、設(shè)計(jì)理念,始終不得要領(lǐng)
  • 目標(biāo)不夠聚焦,閱讀過程容易復(fù)雜化
  • 容易陷入細(xì)節(jié),在不重要的問題上糾結(jié)半天
  • 容易追著分支流程跑,分散注意力
  • 沒有及時(shí)記錄筆記和總結(jié),沒有把知識(shí)碾碎、重組、內(nèi)化成自己的東西
  • 沒有處理過特別復(fù)雜問題的經(jīng)歷,潛在的不自信心理
  • 個(gè)人毅力、韌性不足,或者目標(biāo)感不夠強(qiáng)烈,遇到困難容易放棄
  • 等等

這個(gè)列表還可以繼續(xù)往下拉很長(zhǎng)很長(zhǎng),總之既有我自己主觀認(rèn)知上的限制又有切切實(shí)實(shí)的客觀原因。后來因?yàn)楣ぷ鞯钠鯔C(jī)硬著頭皮看完 Vue 和 mxGraph 的源碼,發(fā)現(xiàn)事情并沒有自己想象中那么困難,后來前前后后陸續(xù)看了很多框架源碼,包括 Webpack、Webpack-sources、Vite、Eslint、Babel、Vue-cli、Vuex、Uniapp、Lodash、Vetur、Echarts、Emmet 等等,愚鈍如我也慢慢摸索出了一些普適的方式方法,進(jìn)而斗膽撰下這篇文章,不敢說授人以漁,但至少也該拋磚引玉吧。

所以這是一篇為哪些有意,或準(zhǔn)備,或已經(jīng)在閱讀前端框架源碼的同學(xué)而寫的文章,我會(huì)在這里拋出一些經(jīng)過我個(gè)人多次實(shí)踐總結(jié)出來的閱讀技巧和原則,并結(jié)合 Vetur 源碼,具體地講解我在閱讀源碼的各個(gè)階段所思所想,希望能給讀者帶來一些啟發(fā)。

弄清楚目標(biāo)

在介紹具體的技巧之前,有必要先跟讀者探討一下閱讀源碼的動(dòng)機(jī),想清楚到底需不需要通過這種方式提升自身技能,雖然學(xué)習(xí)優(yōu)秀框架源碼確實(shí)有非常多不言自明的好處,但每個(gè)人的經(jīng)驗(yàn)、所處的語境、訴求、思維習(xí)慣不同,實(shí)際學(xué)習(xí)效果在不同個(gè)體或個(gè)體的不同時(shí)期必然存在極大的差異,這里面最大的變量一是經(jīng)驗(yàn),二是目標(biāo),經(jīng)驗(yàn)因人而異,且很難在短時(shí)間內(nèi)補(bǔ)齊,沒有太多討論空間;倒是目標(biāo)方面值得盤道盤道。

第一層,先弄清楚為啥要閱讀源碼?可能的原因有很多,例如:

  • 為了增進(jìn)對(duì)框架的認(rèn)知深度,提升個(gè)人能力
  • 為了應(yīng)對(duì)面試
  • 為了解決當(dāng)下某個(gè)棘手的 bug 或性能問題
  • 基于某些原因,需要對(duì)框架做二次改造
  • 反正閑著,也不知道該學(xué)點(diǎn)啥,試試唄。。。
  • 好奇

這里面有一些很抽象,例如最后一個(gè)“好奇”;有一些很具體,例如“為了做二次改造”;還有一些在具體與抽象之間。按照 SMART 原則的說法,越具體、可衡量的目標(biāo)越容易達(dá)成,如果讀者的目標(biāo)還處在比較模棱兩可,不夠具體詳細(xì)的階段,那執(zhí)行過程大概率會(huì)翻車,畢竟這是一件特別消耗精力與耐性的活兒。

對(duì)于這種情況,我的建議是不妨往更細(xì)節(jié)的層次再想一想,例如對(duì)于最后一點(diǎn)“好奇”,可以想想具體有哪些特性讓你特別神奇,值得花時(shí)間精力去細(xì)致地探索,放在 Vetur 語境下可以是“我想了解 Vetur 的 template 錯(cuò)誤提示與 eslint 如何結(jié)合在一起,實(shí)現(xiàn)模板層面的錯(cuò)誤提示功能”,這就很具體很容易衡量了。

第二層,讀者如果已經(jīng)有了明確、具體、可衡量的目標(biāo),不妨在開始之前先自問幾個(gè)問題:

  • 當(dāng)下確實(shí)需要以閱讀源碼的方式增進(jìn)自己對(duì)框架的認(rèn)知深度嗎?有沒有一些更輕量級(jí),迭代速度更快的學(xué)習(xí)方式?
  • 你所選定的框架,其復(fù)雜度、技術(shù)難度是否與你當(dāng)下的能力匹配?最好的狀態(tài)是你自認(rèn)為踮踮腳就能夠到,過高,不具有可行性;過低,ROI 不值當(dāng)。

如果經(jīng)過這番推敲之后,必要性、可行性、相關(guān)性都與個(gè)人目標(biāo)契合,那就沒啥可猶豫的。

第三層,需要辯證地去看待所謂“目標(biāo)” —— 不是把整個(gè)項(xiàng)目完整讀完讀通才叫成功,如果能從一些語句、片段、局部模塊中習(xí)得新的設(shè)計(jì)思維、工具方法,甚至僅僅是命名規(guī)范都可以算作個(gè)人的一點(diǎn)進(jìn)步,積少成多遠(yuǎn)比拔苗助長(zhǎng)靠譜的多。所以一開始沒必要把目標(biāo)定的太高,能剛剛好滿足自身需求是最好的,過程中如果發(fā)現(xiàn)問題域的復(fù)雜度在不斷膨脹變大,持續(xù)投入很多時(shí)間卻始終沒有明顯成效的話,那建議果斷放棄或者請(qǐng)求外援,重新評(píng)估目標(biāo)與可行性之后再做決定。

總之,這是一個(gè)預(yù)期管理的問題,我們可以多參考 SMART 原則,多從具體、可衡量、可行性、相關(guān)性幾個(gè)維度思考,不斷推敲是否需要做這件事;如何拆解目標(biāo),用目標(biāo)反推計(jì)劃,不斷推進(jìn)個(gè)人成功。

閱讀技巧

了解背景知識(shí)

「知識(shí)」是形成「理解」的必要條件,展開學(xué)習(xí)任何一個(gè)開源項(xiàng)目之前都有必要花點(diǎn)時(shí)間調(diào)研項(xiàng)目相關(guān)的基礎(chǔ)知識(shí),漸進(jìn)構(gòu)建起一套屬于你自己的知識(shí)體系,這包括:

  • 優(yōu)質(zhì)參考資料 —— 收集一波質(zhì)量較高的學(xué)習(xí)資料,收集過程可以同步通讀一遍
  • 框架是如何運(yùn)行的 —— 也就是所謂的入口
  • IO —— 框架如何與外部交互?它通常接受什么形態(tài)的運(yùn)行參數(shù)?輸出什么形式的結(jié)果?
  • 生態(tài) —— 優(yōu)秀的框架背后通常都帶有一套成熟的生態(tài)系統(tǒng),例如 Vue,框架衍生品如何補(bǔ)齊框架本身的功能缺失?它們以何種方式,以什么樣的 IO 與主框架交互?遵循怎么樣的寫法規(guī)則?
  • 如何斷點(diǎn)調(diào)試 —— 這幾乎是最有效的分析方法,斷點(diǎn)調(diào)試能夠幫助你細(xì)致地了解每一行代碼的作用。

注意,這里的目標(biāo)是迅速構(gòu)建起關(guān)于這個(gè)開源項(xiàng)目的抽象 —— 甚至不太準(zhǔn)確的知識(shí)框架,有意思地避免陷入無盡的細(xì)節(jié)中,就像在閱讀一篇文章的時(shí)候,可以先看看目錄結(jié)構(gòu)粗略地了解文章的信息框架,了解文章大概內(nèi)容。

例如,我剛開始學(xué)習(xí) Vetur 的時(shí)候只知道這是一個(gè) VS Code 插件,但完全不了解插件怎么寫、怎么運(yùn)行、怎么實(shí)現(xiàn)語言特性,所以我做的第一件事情是仔仔細(xì)細(xì)閱讀 VS Code 的官方文檔(所幸文檔非常齊全,不像某著名打包工具),學(xué)習(xí)關(guān)于插件開發(fā)的基本知識(shí),包括:

進(jìn)一步總結(jié)關(guān)于 VS Code 語言插件的要素:

  • 「怎么寫插件」:通過 package.json 文件的 contributes 、main 等屬性,聲明插件的功能與入口
  • 「怎么運(yùn)行」:開發(fā)階段使用 F5 啟動(dòng)調(diào)試
  • 「怎么編寫語言特性」:使用 「詞法高亮、Language API、Language Server Protocol」 三類技術(shù)實(shí)現(xiàn)

VS Code 領(lǐng)域的知識(shí)量還是很龐大的,學(xué)習(xí)背景知識(shí)并梳理成這種高度結(jié)構(gòu)化、高度抽象的腦圖能夠給你一個(gè)更高層、全面的視角,理想狀態(tài)下,后續(xù)實(shí)際分析源碼的時(shí)候這些骨架脈絡(luò)能夠讓你非常本能地映射到某一個(gè)切面的知識(shí)點(diǎn),事半功倍。

六步循環(huán)分析

接下來,我會(huì)介紹一套我常用的分析流程:

整體分為六個(gè)步驟:

  • 理解項(xiàng)目結(jié)構(gòu)
  • 尋找合適的切入點(diǎn)
  • 就著切入點(diǎn)查閱文章資料
  • 就著切入點(diǎn)分析代碼流程
  • 局部深入研究
  • 及時(shí)總結(jié)

之后,再繼續(xù)設(shè)定切入點(diǎn),重復(fù)執(zhí)行上述流程直到透徹地理解了問題

這是一套在 「總-分-總」 視角之間反復(fù)橫跳最終構(gòu)建出完整視角的方法論,重點(diǎn)就在于告訴讀者在什么階段應(yīng)該關(guān)注什么,忽略什么,輸入什么,輸出什么,我個(gè)人就是按照這個(gè)方法慢慢摸索出包括 Webpack、Babel、Vue、Vetur、mxGraph 在內(nèi)的各種開源框架的實(shí)現(xiàn)原理。

理解項(xiàng)目結(jié)構(gòu)

剛開始閱讀源碼的時(shí)候,相信大多數(shù)人都會(huì)很懵逼,無從下手,這是因?yàn)樽x者對(duì)項(xiàng)目缺乏一個(gè)必要的框架性認(rèn)知,不了解程序的入口在哪里、關(guān)鍵組件有哪些、各個(gè)文件夾有什么作用等,遇到問題無法迅速推測(cè)實(shí)現(xiàn)路徑。

所以,閱讀源碼的第一個(gè)步驟,應(yīng)該是先花點(diǎn)時(shí)間粗淺地分析、理解項(xiàng)目的組織結(jié)構(gòu)。所幸一個(gè)值得深入閱讀學(xué)習(xí)的開源項(xiàng)目,通常都會(huì)有較強(qiáng)的整體性與一致性,我們只需要梳理出三條線索:

  • 分析項(xiàng)目入口
  • 分析項(xiàng)目依賴了哪些基礎(chǔ)工具,包括編譯工具,如 webpack、Typescript、babel;基礎(chǔ)庫(kù),如 lodash、tapable、snabbdom。
  • 將項(xiàng)目中重要文件夾、文件逐一列舉出來,理解它們?nèi)绾伟凑找蕾囮P(guān)系組成一個(gè)整體的架構(gòu)。

放在 vetur 語境下,我們?cè)谏厦?ldquo;了解背景知識(shí)”一節(jié)已經(jīng)了解到 VS Code 插件需要在 package.json 文件通過 contributes 等屬性聲明插件的配置信息,所以這幾個(gè)問題都能在 package.json 文件找到答案。

入口分析

首先,需要識(shí)別出 Vetur 應(yīng)用的入口,這一步的作用是幫助我們理解 Vetur 是如何向 VS Code 貢獻(xiàn)新特性的。分析 vetur 的 package.json 發(fā)現(xiàn)有三種直接指向到文件的配置項(xiàng):

  • contributes.languages 指定語言配置文件
  • contributes.grammars 指定語法配置文件
  • "main": "./dist/vueMain.js" 指定插件執(zhí)行入口

三個(gè)入口分別實(shí)現(xiàn)三種不同的語言特性功能,略顯復(fù)雜,這里有必要分別展開了解一下。

探索 contributes.languages 配置

逐個(gè)講解,contributes.languages 配置信息指向到 ./languages/***-language-configuration.json 文件,如:

  1.     // ... 
  2.     "contributes": { 
  3.         "languages": [ 
  4.             { 
  5.                 "id""vue"
  6.                 "configuration""./languages/vue-language-configuration.json" 
  7.             }, 
  8.             { 
  9.                 "id""vue-html"
  10.                 "configuration""./languages/vue-html-language-configuration.json" 
  11.             } 
  12.             // ... 
  13.         ] 
  14.     } 
  15.     // ... 

這里回過頭翻一下 VS Code 對(duì) [contributes.languages](https://code.visualstudio.com/api/references/contribution-points#contributes.languages) 的解釋(感謝資源豐富的 VS Code 社區(qū)):

Contribute definition of a language. This will introduce a new language or enrich the knowledge VS Code has about a language.

大意是說 contributes.languages 配置項(xiàng)的作用主要是增進(jìn) VS Code 對(duì)具體語言的理解,至于怎么增強(qiáng)呢?繼續(xù)打開配置項(xiàng)中的 ./languages/vue-language-configuration.json 文件:

  1.     "comments": { 
  2.         // symbol used for single line comment. Remove this entry if your language does not support line comments 
  3.         "lineComment""//"
  4.         // symbols used for start and end a block comment. Remove this entry if your language does not support block comments 
  5.         "blockComment": [ 
  6.             "/*"
  7.             "*/" 
  8.         ] 
  9.     }, 
  10.     // ... 

文件中定義了行內(nèi) comment、塊級(jí) comment、括號(hào)、折疊等語言規(guī)則的配置,規(guī)則都很簡(jiǎn)單直白,篇幅關(guān)系這里不展開。

回顧一下探索步驟:

  • 翻閱參考資料,理解 contributes.languages 配置的作用
  • 打開對(duì)應(yīng)入口文件,猜測(cè)各個(gè)配置項(xiàng)的作用
  • 繼續(xù)翻閱參考資料,或者修改配置,驗(yàn)證猜想

探索 contributes.grammars 配置

contributes.grammars 項(xiàng)包含諸多指向到 ./syntaxes/vue-xxx.json 的配置信息,形如:

  1.     "contributes": { 
  2.       "grammars": [ 
  3.         { 
  4.           "language""vue"
  5.           "scopeName""source.vue"
  6.           "path""./syntaxes/vue-generated.json"
  7.           "embeddedLanguages": { 
  8.             "text.html.basic""html"
  9.             // ... 
  10.           } 
  11.         }, 
  12.         { 
  13.           "language""vue-postcss"
  14.           "scopeName""source.css.postcss"
  15.           "path""./syntaxes/vue-postcss.json" 
  16.         } 
  17.         // ... 
  18.       ] 
  19.     } 
  20.   } 

同樣的,我們先查一下官網(wǎng)對(duì) [contributes.grammars](https://code.visualstudio.com/api/references/contribution-points#contributes.grammars) 配置項(xiàng)的解釋:

Contribute a TextMate grammar to a language. You must provide the language this grammar applies to, the TextMate scopeName for the grammar and the file path.

這段描述略微復(fù)雜,大意是開發(fā)者可以通過 grammars 屬性提供關(guān)于語言的 TextMate 形式的語法描述,grammars 配置項(xiàng)包含三個(gè)屬性:

  • language:語言的名稱
  • scopeName:語言的分類,與 TextMate scopeName 同義,可用于嵌套語法定義
  • path:語言的詞法規(guī)則文件

這里面 path 屬性指向一個(gè)內(nèi)容更復(fù)雜的配置文件 ./syntaxes/vue-xxx.json,我們可以接著打開其中任意一個(gè)文件,關(guān)鍵內(nèi)容結(jié)構(gòu)如下:

  1.     "name""Vue HTML"
  2.     "scopeName""text.html.vue-html"
  3.     "fileTypes": [], 
  4.     "uuid""ca2e4260-5d62-45bf-8cf1-d8b5cc19c8f8"
  5.     "patterns": [ 
  6.         // ... 
  7.         { 
  8.             "name""meta.tag.any.html"
  9.             "begin""(<)([A-Z][a-zA-Z0-9:-]*)(?=[^>]*></\\2>)"
  10.             "beginCaptures": { 
  11.                 "1": { 
  12.                     "name""punctuation.definition.tag.begin.html" 
  13.                 }, 
  14.                 "2": { 
  15.                     "name""support.class.component.html" 
  16.                 } 
  17.             } 
  18.         } 
  19.     ], 
  20.     "repository": { 
  21.         // ... 
  22.     } 

按照 Syntax Highlight Guide(https://zjsms.com/e7E5Jdq/) 一節(jié)的說法這里面最重要的是 patterns 屬性,而 patterns 屬性最關(guān)鍵的功能就是以正則語句表達(dá)語言的詞法分析規(guī)則,并分配詞法對(duì)應(yīng)的 name 命名,詳細(xì)的配置規(guī)則還可以繼續(xù)參考 TextMate 官網(wǎng),這里大致理解作用即可,先不展開深究。

探索 main 配置

接著往下看,第三個(gè)值得關(guān)注的是 main 屬性,在 vetur 中對(duì)應(yīng)的值為:

  1. "main""./dist/vueMain.js" 

VS Code 官網(wǎng)對(duì) main 屬性的解釋非常精簡(jiǎn):「The entry point to your extension」,也就是插件的入口,通常需要指向到可執(zhí)行的 JS 文件,插件啟動(dòng)時(shí) VS Code 會(huì)執(zhí)行這個(gè)入口文件導(dǎo)出的 activate 方法,內(nèi)容框架大致為:

  1. import vscode from 'vscode'
  2.  
  3. export async function activate(context: vscode.ExtensionContext) { 
  4.     // ... 啟動(dòng)邏輯 

在 Vetur 中,activate 函數(shù)定義在 client/vueMain.ts 文件,分析源碼可知該函數(shù)主要完成如下事項(xiàng):

  • 調(diào)用 registerXXXCommands 方法注冊(cè)一系列命令
  • 調(diào)用 initializeLanguageClient 方法初始化 LSP Client 對(duì)象

這兩個(gè)操作具體的作用,我們先按下不表,后面再展開。

小結(jié)

對(duì)入口的分析就到這里了,我們先總結(jié)、記錄下關(guān)鍵信息:

  • Vetur 本質(zhì)上是一個(gè) VS Code 插件,所有配置 —— 包括入口都記錄在 package.json 文件中
  • Vetur 包含三種啟動(dòng)入口:
    • contributes.languages:定義一些簡(jiǎn)單的語言基本配置,包括怎么折疊,怎么注釋
    • contributes.grammars:定義了一套基于 TextMate 引擎的詞法規(guī)則,用于實(shí)現(xiàn)代碼高亮
    • main:定義了插件的啟動(dòng)入口,入口中注冊(cè)了一系列命令,同時(shí)創(chuàng)建了基于 LSP 協(xié)議的 Language Client 對(duì)象,而 LSP 協(xié)議用于實(shí)現(xiàn)如代碼補(bǔ)全、錯(cuò)誤診斷、跳轉(zhuǎn)定義等高級(jí)特性

到這里,雖然我們還是不了解 Vetur 的實(shí)現(xiàn)細(xì)節(jié),但是對(duì) Vetur 的背景知識(shí)與項(xiàng)目結(jié)構(gòu)應(yīng)該已經(jīng)有了一個(gè)比較基礎(chǔ)的認(rèn)知,已經(jīng)能大致識(shí)別哪些功能由哪些模塊實(shí)現(xiàn)。

OK,這里先保持好這個(gè)模模糊糊的認(rèn)知就行了,不要花太多時(shí)間。

基礎(chǔ)依賴分析

接下來,需要梳理一下 Vetur 的基礎(chǔ)依賴,這一步的作用是幫助我們理解 Vetur 可能用到哪些基礎(chǔ)技術(shù),比如用到哪些工程化工具、怎么編譯、怎么檢查代碼等。

  • Vetur 的 package.json 文件主要包含三類信息:
  • VS Code 插件配置信息,大體上在上一節(jié)都有描述,這里不展開

工程化命令,核心有:

  • watch:對(duì)應(yīng)命令為 rollup -c rollup.config.js -w ,由此可以推斷 Vetur 基于 Rollup 實(shí)現(xiàn)構(gòu)建
  • compile:功能與 watch 相似
  • lint:對(duì)應(yīng)命令為 tslint -c tslint.json **.ts ,由此可以推斷 Vetur 基于 tslint 實(shí)現(xiàn)代碼檢查

項(xiàng)目的 devDependencies 依賴,主要包含 typescript、tslint、rollup、vscode-languageclient、husky、mocha、vscode-test、prettier

那么,從這些信息我們基本可以推斷出如下信息:

  • Vetur 使用 Rollup + typescript 等工具執(zhí)行構(gòu)建工作,按常理執(zhí)行 yarn watch 命令應(yīng)該就能啟動(dòng)一個(gè)持續(xù)的構(gòu)建工作進(jìn)程
  • Vetur 使用 tslint 實(shí)現(xiàn)代碼檢查,配合 huscky + prettier 完成格式化工作
  • Vetur 使用 mocha + vscode-test 實(shí)現(xiàn)自動(dòng)化測(cè)試

文件結(jié)構(gòu)

接著,還需要稍微展開看看 Vetur 的文件結(jié)構(gòu),這一步能夠一定程度上幫助我們理解 Vetur 的代碼架構(gòu)及要素,推測(cè)各種特性是在什么位置實(shí)現(xiàn)的。Vetur 的文件結(jié)構(gòu)大致上如下:

  1. vetur 
  2. ├─ .vscode 
  3. │  ├─ ... 
  4. ├─ build 
  5. │  ├─ ... 
  6. ├─ client 
  7. │  ├─ client.ts 
  8. │  ├─ commands 
  9. │  │  ├─ ... 
  10. │  ├─ grammar.ts 
  11. │  ├─ ... 
  12. ├─ languages 
  13. │  ├─ vue-html-language-configuration.json 
  14. │  ├─ ... 
  15. ├─ scripts 
  16. │  ├─ build_grammar.ts 
  17. │  └─ tsconfig.json 
  18. ├─ server 
  19. │  ├─ .gitignore 
  20. │  ├─ .mocharc.yml 
  21. │  ├─ .npmrc 
  22. │  ├─ bin 
  23. │  │  └─ vls 
  24. │  ├─ package.json 
  25. │  ├─ rollup.config.js 
  26. │  ├─ src 
  27. │  │  ├─ ... 
  28. ├─ syntaxes 
  29. │  ├─ markdown-vue.json 
  30. │  ├─ pug 
  31. │  │  ├─ ... 
  32. │  ├─ ... 
  33. │  └─ vue.yaml 
  34. ├─ test 
  35. │  ├─ ... 
  36. ├─ vti 
  37. │  ├─ README.md 
  38. │  ├─ bin 
  39. │  │  └─ vti 
  40. │  ├─ package.json 
  41. │  ├─ rollup.config.js 
  42. │  ├─ src 
  43. │  │  ├─ ... 
  44. │  ├─ tsconfig.json 
  45. │  └─ yarn.lock 
  46. ├─ tsconfig.options.json 
  47. ├─ package.json 
  48. ├─ ... 
  49. └─ yarn.lock 

其中,比較關(guān)鍵的有:

  • client:VS Code 插件的入口代碼,package.json 文件中 main 字段會(huì)指向這個(gè)目錄的產(chǎn)物
  • server:LSP 架構(gòu)中的 Server 端,上述 client 會(huì)通過 LSP 協(xié)議與這個(gè) server 目錄通信
  • syntaxes:Vetur 的詞法規(guī)則文件夾,內(nèi)部包含許多 JSON 格式,符合 TextMate 規(guī)則的詞法聲明
  • languages:Vetur 提供的語言配置信息,規(guī)則比較簡(jiǎn)單,了解作用即可,不必深入
  • vti:按 vti/bin/vti 文件可以推斷,這里是 Vetur 的命令行工具,不在主流程內(nèi)可以先忽略
  • docs:按內(nèi)容可以推斷這是 Vetur 的介紹文檔,此處可忽略
  • build:構(gòu)建命令,package.json 文件的 script 命令有一些會(huì)指向這個(gè)目錄,可以忽略
  • 一系列基礎(chǔ)配置文件,包括 tsconfig.json 、package.json 等,可先忽略

我們還可以繼續(xù)往下探索各個(gè)子目錄的內(nèi)容,但是注意淺嘗輒止即可,后面隨著源碼閱讀的深入,讀者對(duì)各個(gè)目錄的理解應(yīng)該會(huì)不斷迭代增長(zhǎng),現(xiàn)在沒必要花太多時(shí)間。

小結(jié)

回顧一下,我們首先學(xué)習(xí)了一些背景知識(shí),之后花了一些時(shí)間分析項(xiàng)目的入口、基礎(chǔ)依賴、文件結(jié)構(gòu),到這里我們基本上可以推斷出:

  • Vetur 是一個(gè)語言插件,所以必然是使用 「詞法高亮、Language API、Language Server Protocol」 三類技術(shù)實(shí)現(xiàn)核心邏輯的,而 package.json 文件中的 contributes 配置項(xiàng)的內(nèi)容也恰好驗(yàn)證了這一點(diǎn)
  • 「詞法高亮」 相關(guān)的代碼集中在 syntaxes 文件夾
  • 「Language Server Protocol」 相關(guān)的代碼集中在 client 與 server 文件夾
  • 可以用 yarn watch 命令持續(xù)構(gòu)建,配合 F5 快捷鍵啟動(dòng)調(diào)試

這些信息是后續(xù)分析源碼的必要條件,而這個(gè)過程跟學(xué)習(xí)一門新語言很類似,讀者可以回想一下最開始學(xué)習(xí) JavaScript 的時(shí)候,有經(jīng)驗(yàn)的學(xué)習(xí)者不會(huì)一上來馬上深入諸如原型、變量提升、事件循環(huán)等語言細(xì)節(jié),而是先以更高層、更抽象的視角學(xué)習(xí) JavaScript 語言的基本骨架,包括函數(shù)、循環(huán)語句、分支判斷語句、對(duì)象等,從而構(gòu)建起一個(gè)抽象的結(jié)構(gòu)化認(rèn)知,后續(xù)再慢慢填充細(xì)節(jié),有點(diǎn)自頂向下的味道。

設(shè)定切入點(diǎn)

在對(duì)項(xiàng)目背景與結(jié)構(gòu)有基本了解之后,我們可以正式開始分析源碼了。首先,讀者要找到一個(gè)匹配自身狀態(tài)和需求的切入點(diǎn),本質(zhì)上就是將大目標(biāo)拆解成一系列小目標(biāo),將大問題拆解成一系列更具體的小問題,然后帶著具體問題更聚焦地去看代碼。

所謂切入點(diǎn)可以直接對(duì)標(biāo)到框架的具體功能,或者某些底層機(jī)制的實(shí)現(xiàn)上,以 Vetur 為例,它實(shí)現(xiàn)了諸多輔助開發(fā) Vue SFC 組件的特性,包括代碼補(bǔ)全、錯(cuò)誤診斷、代碼高亮、跳轉(zhuǎn)到定義、hover 提示等等,這里面任意一個(gè)展開來都有大量可以挖掘的空間,如果從一開始就漫無目的瞎逛亂看那鐵定是看不出個(gè)所以然的,鑒于我的目標(biāo)就是想通過 Vetur 學(xué)習(xí) VS Code 插件的開發(fā)套路,所以選擇了一個(gè)看起來比較簡(jiǎn)單的特性:「代碼補(bǔ)全」 作為第一個(gè)切入點(diǎn),后續(xù)的學(xué)習(xí)經(jīng)歷證明這是一個(gè)非常合適的點(diǎn),不復(fù)雜但是已經(jīng)能幫我窺見 Vetur 的核心工作機(jī)制,以此類推后面分析其它高級(jí)特性如代碼高亮、代碼補(bǔ)全等,基本上就是很輕車熟路的狀態(tài)了。

如果你有一些更明確的目的,比如解決某個(gè)具體的 bug,那你應(yīng)該會(huì)更容易 get 到當(dāng)下最需要做的事情;如果始終抓不到要點(diǎn),那么建議先回到前面“了解背景知識(shí)”或“理解項(xiàng)目結(jié)構(gòu)”的步驟,繼續(xù)探索一些上下文信息,再試試問自己:我接下來到底應(yīng)該先了解哪些具體功能的實(shí)現(xiàn)邏輯?

記住,這并不是一錘子買賣,如果你在后續(xù)的分析過程中發(fā)現(xiàn)這個(gè)切入點(diǎn)變得越來越復(fù)雜,超出最開始的預(yù)期,不要有心理負(fù)擔(dān),這再正常不過了,而且反而側(cè)面表現(xiàn)出你對(duì)問題域有越來越少的理解了,可以回過頭來重新調(diào)整目標(biāo),找一個(gè)更小的切入點(diǎn)。

善用搜索引擎

定下切入點(diǎn)后,首先要做的不是打開代碼咔咔就干,而應(yīng)該首先試試在社區(qū)搜索相關(guān)的資料,畢竟自媒體時(shí)代了,很多開源框架的知識(shí)已經(jīng)被無數(shù)人吃透、捏碎、重組成各種維度的文章,順著這些文章的思路去理解源碼會(huì)比完全靠自己摸索效率高很多。

列舉幾種我常用的搜索渠道:

  • 谷歌 and 百度一類的搜索引擎,體感上谷歌的搜索質(zhì)量會(huì)好很多,不過有一定的英語門檻
  • 開源項(xiàng)目的官網(wǎng)、社區(qū)、wiki、github 等官方渠道,通常都會(huì)有比較不錯(cuò)的資料
  • Segmentfault、知乎、掘金、公眾號(hào)等垂直社區(qū)
  • 國(guó)外的 Medium/StackOverflow 社區(qū),質(zhì)量極高,很多大佬在上面活躍

假如搜了一通找不到答案,可以試試不同的關(guān)鍵詞組合,我經(jīng)常用的關(guān)鍵詞有:

  • Xxx 源碼解析
  • Xxx 原理
  • 如何實(shí)現(xiàn) xxx

假如還是找不到,還可以試試換一個(gè)意思接近的關(guān)鍵詞,繞點(diǎn)彎路??傊褪窍氡M辦法找到有用的,適合當(dāng)下問題的信息,幫助讀者更快更平滑地深入研究源碼,這一步對(duì)新手尤為重要。

 

責(zé)任編輯:武曉燕 來源: Tecvan
相關(guān)推薦

2019-07-26 15:49:25

代碼開發(fā)工具

2016-12-20 12:34:46

存儲(chǔ)MySQL流程

2015-05-07 11:24:13

DockerIT技術(shù)評(píng)價(jià)新技術(shù)

2015-07-01 15:39:52

Ceph云存儲(chǔ)NAS

2018-01-25 08:29:28

Kafka源碼存儲(chǔ)

2018-10-29 12:21:21

源碼前端項(xiàng)目

2021-05-31 08:00:00

消息隊(duì)列架構(gòu)Rabbit MQ

2018-08-22 16:40:51

前端JavascriptVue

2018-11-16 16:35:19

Java源碼編程語言

2018-10-15 11:08:23

2011-07-08 09:55:02

數(shù)據(jù)中心防震

2017-04-13 19:26:21

2021-12-20 07:58:59

GitHub源碼代碼

2021-03-13 14:08:00

Hadoop 源碼HDFS

2022-02-14 14:28:57

驅(qū)動(dòng)開發(fā)鴻蒙系統(tǒng)

2021-04-16 08:20:00

Flink CEP直播監(jiān)控

2022-01-10 12:23:00

TypeScript ESLint前端

2009-03-02 16:57:34

LinuxUbuntu配置完全方案

2021-01-14 09:00:00

開發(fā)FedoraUbuntu

2020-12-07 11:29:24

ReactVueVue3
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)