小姐姐筆記:我是如何學習簡單源碼拓展視野的

大家好,我是若川。這是我上周組織的源碼共讀紀年小姐姐的筆記,寫得很好。所以分享給大家。歡迎加我微信 ruochuan12,進源碼共讀群。其他更多人的筆記可以閱讀原文查看。


川哥的源碼解讀文章:據說 99% 的人不知道 vue-devtools 還能直接打開對應組件文件?本文原理揭秘

???? 非常感謝川哥組織的源碼閱讀活動

1. 解讀前的準備

1.1 粗略閱讀一遍川哥的源碼解讀文章,弄清楚文章的主旨內容:探究 vue-devtools「在編輯器中打開組件」功能實現原理**,它的核心實現就是 launch-editor**。

1.2 明確自己到底要學習什么:

1)學習調試源碼的方法;

2)在調試過程中探究 launch-editor 源碼是如何實現在編輯器打開對應的文件;

目標:跟著川哥的文章完整走完一遍調試的流程,并對外輸出記錄文檔。

1.3 資源:

  • 下載川哥的源碼:git clone https://github.com/lxchuan12/open-in-editor.git,進入 vue3-project 目錄,安裝依賴yarn install

  • 安裝 vue-devtools 谷歌擴展:翻墻去應用商店下載安裝即可(下載 6.0.0 beta 版)

  • 了解 launch-editor[1]:主要功能是在編輯器中打開帶有行號的文件

2. 開始學習,淺嘗輒止

上述的準備工作搞完之后,我們動手操作一下。

2.1 開始動手

我使用的編輯器是 VSCode。

打開 vue3-project 目錄的 package.json,點擊調試,選擇 serve。這一步操作,使得我們以 debug 的形式,運行了 vue-cli-service serve 這個命令。

img

跟著文章實現到這里的時候,我有點懵逼,因為我不知道接下來為什么突然要搜索【launch-editor-middleware】這個庫。

直到我再次通讀一遍文章,發現川哥前面有提到 vue-devtools 的 Open component in editor[2] 這個文檔,這個文檔里面描述了引用了【launch-editor-middleware】這個庫來實現打開文檔的功能。而我之前先入為主地以為,這期是解讀 vue-devtools 的源碼,其實這只是解讀實現打開文檔功能的源碼而已。

理解了這一層,我們可以直接搜項目里(包括 node_modules)里的【launch-editor-middleware】關鍵字,就可以找到這個庫的源碼位置了。

2.2 調試之旅

調試的流程就是打斷點,點擊調試的流程面板,經過不斷調試,觀察數據的變化。

下圖【launch-editor-middleware】的源碼,在這份源碼中我們能很輕易地分析出,最終運行的是 launch 函數,我們可以這這里打一個斷點,然后進入到【launch-editor】的源碼,實際運行的是 launchEditor 函數。

img
img

粗略看一遍 launchEditor 函數,發現它實際上是做了四件事:

  • 獲取 fileName,lineNumber,columnNumber

  • 異常處理:是否存在文件,onErrorCallback,是否存在 editor

  • 猜測當前正在使用的編輯器:guessEditor

  • 使用 child_process.spwan 異步打開一個子進程模塊,它調起了 cmd.exe 工具打開我們的編輯器,并打開了文件(args 就是文件的參數)

看完了這個函數,其實大概實現的原理也就出來了,核心代碼如下:

if?(process.platform?===?'win32')?{_childProcess?=?childProcess.spawn('cmd.exe',['/C',?editor].concat(args),{?stdio:?'inherit'?})
}?else?{_childProcess?=?childProcess.spawn(editor,?args,?{?stdio:?'inherit'?})
}

但我們肯定還有很多疑惑,比如:

  • 在瀏覽器控制臺點擊按鈕,編輯器是怎么接收到它的請求信息呢?

  • 用到了哪些 API/編程技巧?

  • 這個功能實現如果讓我們來實現,是怎么實現呢(復述思路)?

3. 動手操作,深入實踐

在前面的拆解中,雖然很多地方看似看懂了,但又沒完全懂,那我們來解答一下在看源碼的時候的疑問:

3.1 編輯器如何接收到瀏覽器的請求信息

點擊 vue-devtools 的按鈕時,我們會發現它發送了一個請求:http://localhost:8080/__open-in-editor?file=src/components/HelloWorld.vue

img

那編輯器是如何接收到這個請求呢?搜索【launch-editor-middleware】關鍵字,我們會發現,在 @vue/cli-service 的 serve.js 文件中,使用了 app.use("/__open-in-editor"),用過 express 的小伙伴會比較熟悉,這是express 引入中間件的用法。當瀏覽器發送 http://localhost:8080/__open-in-editor?file=src/components/HelloWorld.vue 這個請求的時候,就進入到下面這個代碼了。

//?vue3-project/node_modules/@vue/cli-service/lib/commands/serve.js
//?46行
const?launchEditorMiddleware?=?require('launch-editor-middleware')
//?192行
before?(app,?server)?{//?launch?editor?support.//?this?works?with?vue-devtools?&?@vue/cli-overlayapp.use('/__open-in-editor',?launchEditorMiddleware(()?=>?console.log(`To?specify?an?editor,?specify?the?EDITOR?env?variable?or?`?+`add?"editor"?field?to?your?Vue?project?config.\n`)))//?省略若干代碼...
}

3.2 用到了哪些 API/編程技巧

3.2.1 函數的重載

在【launch-editor-middleware】的入口函數這里,使用了函數重載的寫法,這種寫法在很多源碼中都很常見,目的是方便用戶調用時傳參,針對不定量的參數對應不同的操作內容。

//?vue3-project/node_modules/launch-editor-middleware/index.js
const?url?=?require('url')
const?path?=?require('path')
const?launch?=?require('launch-editor')module.exports?=?(specifiedEditor,?srcRoot,?onErrorCallback)?=>?{//?specifiedEditor?=>?這里傳遞過來的則是?()?=>?console.log()?函數//?所以和?onErrorCallback?切換下,把它賦值給錯誤回調函數if?(typeof?specifiedEditor?===?'function')?{onErrorCallback?=?specifiedEditorspecifiedEditor?=?undefined}//?如果第二個參數是函數,同樣把它賦值給錯誤回調函數//?這里傳遞過來的是undefinedif?(typeof?srcRoot?===?'function')?{onErrorCallback?=?srcRootsrcRoot?=?undefined}//?srcRoot?是傳遞過來的參數,或者當前?node?進程的目錄srcRoot?=?srcRoot?||?process.cwd()//?最后返回一個函數,?express?中間件return?function?launchEditorMiddleware?(req,?res,?next)?{//?省略?...}
}

3.2.2 裝飾器模式

這段代碼 wrapErrorCallback 先執行其他代碼,再去執行 onErrorCallback,這種包裹函數的形式在很多源碼里都也很常見,可以理解為一個裝飾器,把 onErrorCallback 包裝了起來,對原函數進行了增強。

這也是設計模式中的裝飾器設計模式:

function?wrapErrorCallback?(cb)?{return?(fileName,?errorMessage)?=>?{console.log()console.log(chalk.red('Could?not?open?'?+?path.basename(fileName)?+?'?in?the?editor.'))if?(errorMessage)?{if?(errorMessage[errorMessage.length?-?1]?!==?'.')?{errorMessage?+=?'.'}console.log(chalk.red('The?editor?process?exited?with?an?error:?'?+?errorMessage))}console.log()if?(cb)?cb(fileName,?errorMessage)}
}onErrorCallback?=?wrapErrorCallback(onErrorCallback)

3.2.3 apply

apply 語法:func.apply(thisArg, [argsArray]),也經常在源碼中可以看到。這里使用 apply 是把 extraArgs 作為 push 方法的 arguments 傳進去。

if?(lineNumber)?{//?getArgumentsForPosition?返回一個數組const?extraArgs?=?getArgumentsForPosition(editor,?fileName,?lineNumber,?columnNumber)//?將?extraArgs?參數?push?到?args?里args.push.apply(args,?extraArgs)
}?else?{args.push(fileName)
}

3.2.4 child_process

child_process 是 Node.js 的一個模塊,它提供了衍生子進程的能力,默認情況下,會在父 Node.js 進程和衍生的子進程之間建立 stdin、stdout 和 stderr 的管道。

3.2.5 process.platform

用于標識運行 Node.js 進程的操作系統平臺,返回字符串,目前可能的值有:?"aix" | "darwin" | "freebsd" | "linux" | "openbsd" | "sunos" | "win32"

3.3 如何實現(復述思路)

  • 瀏覽器與編輯器的通訊:借助 Node.js 進程,與瀏覽器發生通訊

  • 瀏覽器將需要打開的文件路徑通過參數傳遞給編輯器

  • 判斷操作系統平臺和所使用的編輯器(每個平臺的命令行程序不一樣,每個編輯器的環境變量也不一樣)

  • 借助 Node 調起 cmd.exe 工具打開我們的編輯器,打開對應路徑的文件

//?偽代碼
app.use("__open-in-editor",?handleLaunchEditor)function?handleLaunchEditor(filePath)?{const?platform?=?process.platformconst?editor?=?guessEditor()childProcess.spawn(editor,?fileArgs,?{?stdio:?'inherit'?})
}

4. 感想

  • 編碼能力:通過解讀 launch-editor 源碼,學習/重溫了【函數的重載】【裝飾器模式】【apply 使用方法】,源碼的組織結構也非常值得我們學習,比如里面很多功能代碼都單獨封裝起來,封裝成函數或者模塊,使得整個源碼的結構非常清晰,核心通俗易懂,易于解讀和維護。(這也可以理解為自頂向下的編程方法)

  • 拓展視野:源碼中包含了很多與 Node.js 相關的方法,有很多都是我不熟悉的,在解讀源碼的過程也是我學習 Node.js 的過程。

  • 工作中可能會用到:

    • 開發 VSCode 插件與外界通訊可借助 Node.js 進程

    • 裝飾器模式的應用

    • 判斷操作系統平臺

參考資料

[1]

launch-editor: https://github.com/yyx990803/launch-editor

[2]

Open component in editor: https://github.com/vuejs/devtools/blob/legacy/docs/open-in-editor.md


最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進群。


推薦閱讀

我在阿里招前端,該怎么幫你(可進面試群)
我讀源碼的經歷

面對 this 指向丟失,尤雨溪在 Vuex 源碼中是怎么處理的
老姚淺談:怎么學JavaScript?

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》多篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,活躍在知乎@若川,掘金@若川。致力于分享前端開發經驗,愿景:幫助5年內前端人走向前列。

識別方二維碼加我微信、拉你進源碼共讀

今日話題

略。歡迎分享、收藏、點贊、在看我的公眾號文章~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275584.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275584.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275584.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php表決器代碼,三人表決器:VHDL源代碼

描述--三人表決器(三種不同的描述方式) vhdl-- Three-input Majority Voter-- The entity declaration is followed by three alternative architectures which achieve the same functionality in different ways.ENTITY maj ISPORT(a,b,c : IN BIT; m : OUT BIT);END maj;--D…

保持危機感和緊迫感_什么是緊迫的:您需要知道的一切

保持危機感和緊迫感Putting the finishing touches on a graphic design project calls for a keen eye. But you already know this, because perfectionism is just a part of the job! You look at every nook and cranny of a project before you can consider it complete…

劍指offer java版(一)

二維數組中的查找 問題描述 在一個二維數組中(每個一維數組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷…

如何系統搭建現代 Web CI/CD

大家好,我是若川。今天分享一篇00后寫的CI/CD直播文字稿。之前發過他的故事:一位00后前端2年經驗的成長歷程。我最近組織了源碼共讀活動,感興趣的加我微信 ruochuan12。本次直播錄播鏈接:https://live.juejin.cn/4354/595741[1]開…

sqlserver oracle 數據類型對應關系,SQLSERVER和ORACLE數據類型對應關系詳解和對應表格整理...

Oracle SQLServer 比較 SQLServer 常見的 數據 庫 類型 字符 數據 類型 CHAR CHAR :都是固定長度字符資料但oracle里面最大度為2kb,SQLServer里面最大長度為8kb 變長字符 數據 類型 VARCHAR2 VARCHAR :racle里面最大長度為4kb,SQLServer里面最大長度為8k…

優化算法匯總

interior point block coordinate relaxation Boltzmann machine 求解L1范數最小化 E. Candes, M. B. Wakin, and S. P. Boyd, “Enhancing sparsity by reweighted l1 minimization,” Journalof Fourier Analysis and Applications, vol. 14, pp. 877-905, Dec. 2008.I. Daub…

對接百度地圖API

一、準備工作 百度地圖開發文檔 注冊百度賬號&#xff0c;成為開發人員&#xff0c;同時獲取AK實例代碼&#xff1a;<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content&quo…

ui邊框設計圖_UI設計形狀和對象基礎知識:填充和邊框

ui邊框設計圖第2部分 (Part 2) Welcome to the second part of the UI Design shapes basics. This time we’ll cover two of the most essential properties of a shape — fills and borders. This is also a part of the free chapters from Designing User Interfaces.歡迎…

如何移除項目中無用的 console.log 代碼

大家好&#xff0c;我是若川。早些天時&#xff0c;我看到一個后端公眾號發《辭退了一個前端》&#xff0c;當時還想著現在后端公眾號都開始吊打前端了嘛。其中有個理由就是線上還一堆console.log...我猜很多人都會移除項目中無用的console.log。可以復習一下。前言說起console…

WCF - 服務實例管理模式

WCF 提供了三種實例上下文模式&#xff1a;PreCall、PreSession 以及 Single。開發人員通過 ServiceBehavior.InstanceContextMode 就可以很容易地控制服務對象的實例管理模式。而當 WCF 釋放服務對象時&#xff0c;會檢查該對象是否實現了 IDisposable 接口&#xff0c;并調用…

oracle io lost,磁盤IO故障

測試工作正在如火如荼的進行&#xff0c;突然數據庫就連接不上了。我連接上主機發現數據庫alert_sid日志中有如下信息&#xff1a;KCF: write/open error block0x9a6 online1file2 /oracle_data1/UNDOTBS3.dbferror27072 txt: Linux Error: 5: Input/output errorAdditional in…

易思匯完成近億元B輪融資,信中利投資

3月19日消息&#xff0c;近日&#xff0c;留學生在線付費平臺易思匯宣布已在3月份完成由信中利投資的近億元B輪融資。 易思匯聯合創始人高宇同表示&#xff0c;本輪融資將主要用于留學生信用卡、留學家庭金融商城等新產品布局&#xff0c;以及擴大團隊和市場投入。 易思匯成立…

遠程連接 錯誤 內部錯誤_關于錯誤的性質和原因。 了解錯誤因素

遠程連接 錯誤 內部錯誤Back in 2012, I was a young[er] product designer working in a small tech agency in Valencia, Spain. In parallel, I worked as a freelancer on several side projects for different clients. One day I was contacted by a new health services…

得到鵝廠最新前端開發手冊一份

又逢金九銀十&#xff0c;拿到大廠offer一直是程序員朋友的目標&#xff0c;但是去大廠就得拿出實力來。除了需要積累技術&#xff0c;了解并掌握面試的技巧&#xff0c;熟悉大廠面試流程&#xff0c;也必不可少。這里分享一份最新入職騰訊的前端社招面經&#xff0c;來看看鵝廠…

性能測試分析之帶寬瓶頸的疑惑

第一部分&#xff0c; 測試執行 先看一圖&#xff0c;再看下文 這個當然就是壓力過程中帶寬的使用率了&#xff0c;我們的帶寬是1Gbps的&#xff0c;合計傳輸速率為128MB/s&#xff0c;也正因為這個就讓我越來越疑惑了&#xff0c;不過通過壓力過程中的各項數據我又不得不相信。…

Android 中的LayoutInflater的理解

LayoutInflater與findViewById的區別&#xff1f; 對于一個已經載入的界面&#xff0c;就可以使用findViewById()方法來獲得其中的界面元素。對于一個沒有被載入或者想要動態載入的界面&#xff0c;就需要使用LayoutInflater對象的inflate()方法來載入。findViewById()是查找已…

linux rootfs編譯進內核,九鼎x6818開發板筆記:uboot、kernel、rootfs編譯和燒寫

下面記錄了如何搭建嵌入開發環境&#xff0c;如何編譯uboot、kernel、和文件系統&#xff0c;如何燒寫鏡像以及如何配置uboot環境變量。閱讀注意&#xff1a;記錄中(Base框中的內容)一些操作故意被添加&#xff0c;為了展示文件內容&#xff0c;故意調用cat(Ubuntu)或者type(wi…

figma下載_素描vs Figma困境

figma下載I distinctly remember how much hatred I had in my heart when I lived through my first UI update. The year was 2009; I had just gotten my braces off and I was ready to smash that ‘Like’ button on my high school crush’s status when I logged into …

祝大家七夕快樂,邀你源碼共讀,順帶發點紅包

大家好&#xff0c;我是若川。這是一個普通的周六。只不過又叫七夕節&#xff0c;祝大家七夕節快樂~所以就不更新技術文了。估計還是有很多讀者不知道我。若川名字由來是取自&#xff1a;上善若水&#xff0c;海納百川。順便放兩篇文章。我讀源碼的經歷&#xff0c;跟各位讀者朋…

windows 系統監視器 以及建議閥值

windows 系統監視器 以及建議閥值 計數器的說明可以在添加計數器那邊 資源 對象\計數器建議的閾值注釋磁盤Physical Disk\% Free SpaceLogical Disk\% Free Space15%磁盤Physical Disk\% Disk Time Logical Disk\% Disk Time90%磁盤Physical Disk\Disk Reads/sec、Physical Dis…