成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么說(shuō) 90% 的前端不會(huì)調(diào)試 Ant Design 源碼?

開(kāi)發(fā) 前端
antd 是 react 主流組件庫(kù),我們經(jīng)常使用它但可能并沒(méi)有調(diào)試過(guò)它的源碼。我們可以在 renderWithHooks 里調(diào)用函數(shù)組件的地方打個(gè)條件斷點(diǎn),在調(diào)用想調(diào)試的組件時(shí)斷住,這樣我們就可以 step into 到該組件定義的地方。

寫 react 項(xiàng)目的小伙伴應(yīng)該都用過(guò) antd 組件庫(kù),但絕大多數(shù)同學(xué)并沒(méi)有看過(guò)它的源碼。

而想深入掌握 antd 組件庫(kù),只熟悉參數(shù)是不行的,必須要深入到源碼層面。

所以今天就來(lái)分享下如何調(diào)試 antd 的源碼。

而且我敢說(shuō)這種調(diào)試源碼的方式 90% 的前端都不會(huì)。

為什么呢?看到后面你就知道了。

首先,我們用 create-react-app 創(chuàng)建一個(gè) react 項(xiàng)目:

yarn create react-app antd-react-test

創(chuàng)建成功后,進(jìn)入到項(xiàng)目里,把 dev server 跑起來(lái)。

圖片

瀏覽器訪問(wèn)可以看到渲染出的頁(yè)面:

圖片

然后我們安裝 antd,在入口組件里引入樣式和 Button 組件:

圖片

頁(yè)面會(huì)顯示這個(gè) Button:

圖片

那怎么調(diào)試這個(gè) Button 組件的源碼呢?

可以這樣:

首先,創(chuàng)建一個(gè) VSCode 調(diào)試配置:

圖片

指定調(diào)試的 URL,然后啟動(dòng)調(diào)試。

在組件里打個(gè)斷點(diǎn),代碼會(huì)在這里斷住:

圖片

可以看到調(diào)用棧中上一幀是 renderWithHooks,這就是 react 源碼里調(diào)用函數(shù)組件的地方。

點(diǎn)擊那個(gè)調(diào)用棧,你就會(huì)看到:

圖片

它調(diào)用了 App 的函數(shù)組件,傳入了參數(shù),拿到渲染后的 children 做后續(xù)處理。

所有函數(shù)組件都是在這里被調(diào)用的,而 antd 的組件也全部是函數(shù)組件,那么我們?cè)谶@里加個(gè)斷點(diǎn),打名字為 Button 的函數(shù)組件被調(diào)用的時(shí)候斷住不就行了?

這種在某種條件下才斷住的情況可以用條件斷點(diǎn):

右鍵選擇添加條件斷點(diǎn):

圖片

輸入斷住的條件:

圖片

當(dāng)組件名字包含 Button 的時(shí)候才斷住。

然后刷新:

圖片

你會(huì)看到 App 組件明明也是函數(shù)組件,卻沒(méi)有在這里斷住,而 InternalButton 在這里斷住了。

這就是條件斷點(diǎn)的作用。

這個(gè) InternalButton 就是  antd 里的 Button 組件。

step into 進(jìn)入函數(shù)內(nèi)部:

圖片

你會(huì)發(fā)現(xiàn)這確實(shí)是 Button 組件的源碼,但卻是被編譯后的,比如 jsx 都被編譯成了 React.createElement:

圖片

這樣是可以調(diào)試 Button 組件源碼的,但是比較別扭。

那能不能直接調(diào)試 Button 組件對(duì)應(yīng)的 tsx 源碼呢?

可以的,這就要用到 sourcemap 了。

我們得把 antd 的源碼下載下來(lái)(我下載的時(shí)候是 4.23):

git clone --depth=1 --single-branch git@github.com:ant-design/ant-design.git

下載的時(shí)候加個(gè) --single-branch 是下載單個(gè)分支, --depth=1 是下載單個(gè) commit, 這樣速度會(huì)快幾十倍,是個(gè)有用的加速小技巧。

antd 下載下來(lái),安裝完依賴之后,我們開(kāi)始 build。

但你會(huì)發(fā)現(xiàn) package.json 中有 build 命令,有 dist 命令,該執(zhí)行哪個(gè)呢?

這個(gè)就需要了解下 antd 的幾種入口了。

去 react 項(xiàng)目的 node_modules 下,找到 antd 的 package.json 看一下,你會(huì)發(fā)現(xiàn)它有三種入口:

圖片

main 是 commonjs 的入口,也就是 require('antd') 的時(shí)候會(huì)走這個(gè)。

module 是 esm 的入口,也就是 import xx from 'antd' 的時(shí)候會(huì)走這個(gè)。

unpkg 是 UMD 的入口,也就是通過(guò) script 標(biāo)簽引入的時(shí)候或者 commonjs 的方式等都可以用。

分別對(duì)應(yīng)了 lib、es、dist 的目錄。

所以 antd 項(xiàng)目里的 dist 命令就是單獨(dú)生成 UMD 代碼的,而 build 命令是生成這三種代碼。

這三種形式的代碼都是可用的,這里我們選擇構(gòu)建 UMD 形式的代碼,因?yàn)樗鼤?huì)用 webpack 打包,而另外兩種是通過(guò) gulp 構(gòu)建的。我對(duì) webpack 更熟悉一些。

執(zhí)行 npm run dist,就會(huì)構(gòu)建出 dist 目錄,下面是 UMD 的代碼:

圖片

圖片

你會(huì)發(fā)現(xiàn)默認(rèn)的構(gòu)建就是會(huì)生成 sourcemap 的,其實(shí)你去那個(gè) react 測(cè)試項(xiàng)目里看下,從 npm 下載的 antd 包也帶了 sourcemap:

圖片

那直接用 dist 入口的代碼就能調(diào)試源碼了么?

我們?cè)囈幌拢?/p>

圖片

把引入組件的地方換成 dist 目錄下,也就是用 UMD 形式的入口。

重新跑調(diào)試:

你會(huì)發(fā)現(xiàn)代碼確實(shí)比之前更像源碼了。

之前前面是這樣的:

圖片

現(xiàn)在是這樣:

圖片

也就是沒(méi)了 babel runtime 的代碼,這明顯是源碼了。

但是你往后看:

之前是這樣的:

圖片

現(xiàn)在是這樣:

圖片

依然還是 React.createElement,而不是 jsx,也沒(méi)有 ts 的代碼。

說(shuō)明它還不是最初的源碼。

為什么會(huì)出現(xiàn)這種既是源碼又不是源碼的情況呢?

因?yàn)樗木幾g流程是這樣的:

圖片

代碼經(jīng)過(guò)了 tsc 的編譯,然后又經(jīng)過(guò)了 babel 的編譯,最后再通過(guò) webpack 打包成 bundle.js。

tsc 和 babel 的編譯都會(huì)生成 sourcemap,而 webpack 也會(huì)生成一個(gè) sourcemap。

webpack 的 sourcemap 默認(rèn)只會(huì)根據(jù)最后一個(gè) loader 的 sourcemap 來(lái)生成。

所以說(shuō)上面我們用了 sourcemap 之后只能關(guān)聯(lián)到 babel 處理之前的代碼,像 ts 語(yǔ)法、jsx 代碼這些都沒(méi)有了。

因?yàn)闆](méi)有關(guān)聯(lián)更上一級(jí)的 ts-loader 的 sourcemap,自然是沒(méi)法直接映射回源碼的。

所以想映射回最初的 tsx 源碼,只要關(guān)聯(lián)了每一級(jí) loader 的 sourcemap 就可以了。而這個(gè)是可以配置的,就是 devtool。

devtool 可以設(shè)置 soruce-map,就是生成 sourcemap,但是這個(gè)不會(huì)關(guān)聯(lián) loader 的 sourcemap。

還可以設(shè)置 cheap-module-source-map,這個(gè) module 就是關(guān)聯(lián) loader 的 soruce-map 的意思。(那個(gè) cheap 是只保留行的 sourcemap,生成速度會(huì)更快)

思路理清楚了,我們?nèi)ジ南戮幾g配置:

antd 的編譯工具鏈在 @ant-design/tools 這個(gè)包里,從 antd/node_modules/@antd-design/tools/lib/getWebpackConfig.js 就可以找到 webpack 的配置:

圖片

搜一下 ts-loader,你就會(huì)看到這段配置:

圖片

確實(shí)就像我們分析的,tsx 會(huì)經(jīng)過(guò) ts-loader 和 babel-loader 的處理。

搜一下 devtool,你會(huì)發(fā)現(xiàn)它的配置是 source-map:

圖片

這就是 antd 雖然有 sourcemap,但是關(guān)聯(lián)不到 tsx 源碼的原因。

那我們給它改一下:

把 devtool 改為 cheap-module-source-map。

并且改一下 babel 配置,設(shè)置 sourceMap 為 true,讓它生成 sourcemap。

圖片

ts也同樣要生成 sourcemap,不過(guò)那個(gè)是在根目錄的 tsconfig.json里改:

圖片

改完這三點(diǎn)之后,再重新跑 npm run dist。

dist 目錄下會(huì)生成新的 antd.js 和 antd.js.map。

圖片

把它復(fù)制到 react 項(xiàng)目的 node_modules/antd/dist 下,覆蓋之前的。

清一下 babel-loader 的緩存:

圖片

重新跑 dev server。

注意,這里要用 dist 下的代碼:

圖片

然后再跑到斷點(diǎn)的位置,進(jìn)入組件源碼,你會(huì)進(jìn)入一個(gè)新世界:

圖片

ts 類型、jsx 的語(yǔ)法,熟悉的感覺(jué)又回來(lái)了,這不就是 antd 組件的源碼么!

圖片

你可以斷點(diǎn)調(diào)試 antd 的參數(shù)是怎么處理的,什么參數(shù)會(huì)走什么邏輯等。

這個(gè)完全不影響正常開(kāi)發(fā),也就是把 antd 換成了從 antd/dist/antd 引入而已,開(kāi)發(fā)完了換回去就行。

現(xiàn)在開(kāi)發(fā) antd 組件還有看文檔么?

直接看源碼它不更香么!

有的同學(xué)可能會(huì)擔(dān)心 node_modules 下的改動(dòng)保存不下來(lái)。

這個(gè)也不是問(wèn)題,可以執(zhí)行下 npx patch-package  antd,會(huì)生成這樣一個(gè) patch 文件:

圖片

patch 文件里記錄了你對(duì) antd 包的改動(dòng),這個(gè)可以上傳到 git 倉(cāng)庫(kù),其他小伙伴拉下來(lái)再執(zhí)行 npx patch-package 就會(huì)自動(dòng)應(yīng)用這些改動(dòng)。

至此,我們成功的調(diào)試了 antd 組件的 tsx 源碼。

為什么說(shuō) 90% 的前端不會(huì)調(diào)試它的源碼呢?

主要是涉及的技術(shù)比較多:

  • VSCode Chrome Debugger 調(diào)試網(wǎng)頁(yè),這個(gè)知道的人就不多
  • react 源碼里 renderWithHooks 是調(diào)用函數(shù)組件的地方
  • 條件斷點(diǎn)可以在滿足條件的時(shí)候斷住
  • antd 的 esm、commonjs、UMD 三種入口
  • sourcemap 是干啥的,雖然經(jīng)常接觸,但還是有很多前端沒(méi)用過(guò)
  • webpack 的 cheap-module-source-map 的含義,為什么需要關(guān)聯(lián) loader 的 sourcemap

而調(diào)試 antd 的組件源碼需要綜合運(yùn)用這些技術(shù),難度還是比較高的。

總結(jié)

antd 是 react 主流組件庫(kù),我們經(jīng)常使用它但可能并沒(méi)有調(diào)試過(guò)它的源碼。

我們可以在 renderWithHooks 里調(diào)用函數(shù)組件的地方打個(gè)條件斷點(diǎn),在調(diào)用想調(diào)試的組件時(shí)斷住,這樣我們就可以 step into 到該組件定義的地方。

但是這樣調(diào)試的并不是最初的源碼,沒(méi)有 jsx 和 ts 語(yǔ)法。

想調(diào)試最初的 tsx 源碼需要用 sourcemap。

antd 有三種入口:es 目錄對(duì)應(yīng) esm 入口,lib 目錄對(duì)應(yīng) commonjs 入口,dist 目錄對(duì)應(yīng) UMD 入口。

把 antd 代碼下載下來(lái),執(zhí)行 npm run dist 就可以生成 UMD 形式的代碼。

想要 sourcemap 映射到 tsx 源碼,需要把 devtool 設(shè)置成 cheap-module-source-map,然后開(kāi)啟 babel-loader 和 ts-loader 的 sourcemap。

把產(chǎn)物覆蓋 antd 的 dist 下的產(chǎn)物,再調(diào)試就可以直接調(diào)試 antd 組件的 tsx 源碼了。

用 antd 組件寫業(yè)務(wù)邏輯之余,對(duì)什么組件感興趣,可以順便去看看它的源碼,它不香么?

責(zé)任編輯:武曉燕 來(lái)源: 神光的編程秘籍
相關(guān)推薦

2019-11-14 09:55:35

開(kāi)發(fā)技能代碼

2015-04-24 13:59:41

2022-09-13 18:55:09

React組件fromJS

2019-04-03 16:24:02

電腦重啟Windows 10

2019-04-03 09:44:37

技術(shù)研發(fā)開(kāi)發(fā)

2021-02-18 08:35:41

阿里開(kāi)源源碼

2019-08-07 15:51:15

5G網(wǎng)絡(luò)運(yùn)營(yíng)商

2014-09-22 09:27:57

Python

2020-12-20 17:37:38

Java開(kāi)發(fā)代碼

2011-11-08 09:18:42

云計(jì)算開(kāi)源OpenStack

2020-01-15 08:42:16

TCP三次握手弱網(wǎng)絡(luò)

2015-07-22 16:46:13

Windows 11理由

2013-08-23 14:22:45

SA系統(tǒng)管理員運(yùn)維

2020-09-04 15:34:07

C編程語(yǔ)言開(kāi)發(fā)

2022-03-14 08:33:09

TypeScriptJavaScript前端

2020-07-03 14:05:26

Serverless云服務(wù)商

2021-11-29 18:27:12

Web Wasmjs

2021-12-21 06:09:05

Python切片索引

2017-02-16 07:37:19

前端程序軟件

2015-02-09 13:23:17

創(chuàng)業(yè)
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 一级免费看 | 99国内精品久久久久久久 | 日日夜夜天天干 | 久久成人国产精品 | 精精国产xxxx视频在线播放 | 亚州中文字幕 | 国产成人jvid在线播放 | 国产一级免费视频 | 久久久精品日本 | 一区二区在线免费观看 | 日本久草视频 | 国产日韩一区二区 | 精品久久久久久中文字幕 | 欧美日韩中文在线观看 | av免费网站在线观看 | 国产精品一区久久久 | 国产精品久久久久久久久久免费 | 欧美5区 | 美美女高清毛片视频免费观看 | 成人网址在线观看 | 91久久精品一区二区二区 | 成人av在线播放 | 免费在线黄色av | 91久久精品一区二区三区 | 国产乱码精品1区2区3区 | 国产乱码精品一品二品 | 久久久青草婷婷精品综合日韩 | 精品一区二区三区中文字幕 | 日本精品久久久一区二区三区 | 日本欧美黄色片 | 久久国产精品免费一区二区三区 | 欧美a在线| 日韩精品成人在线 | 粉嫩一区二区三区四区公司1 | 精品久久久久久久 | 操人视频在线观看 | 四虎免费视频 | 亚洲欧美在线观看 | 成年精品 | 精品国产一区二区三区久久狼黑人 | 北条麻妃99精品青青久久主播 |