亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

React 源碼調(diào)試方式

 更新時間:2022年08月09日 16:31:26   作者:zxg_神說要有光  
這篇文章主要為大家介紹了React源碼調(diào)試方式實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

什么?調(diào)試 React 源碼還有優(yōu)雅和不優(yōu)雅之分?

別著急,我們先來聽個故事:

東東是一名前端工程師,主要用 React 技術(shù)棧,用了多年之后想深入一下,所以最近開始看 React 源碼。

斷點(diǎn)調(diào)試

他把 react 和 react-dom 包下載了下來,在項(xiàng)目里引入,開發(fā)服務(wù)跑起來后,打開 Chrome Devtools 打斷點(diǎn)調(diào)試。

這樣調(diào)試了一段時間之后,他有了一些困惑:

這樣調(diào)試是可以的,但是總感覺和源碼有段距離,因?yàn)檎{(diào)試的是 react-dom.development.js

搜索定位

而源碼里這些邏輯是分散在不同的包里的,所以就算搞懂了邏輯,也不知道這些邏輯在哪些包里,只能靠搜索來定位。

所以他就在想,是不是有更好的調(diào)試方式,能夠調(diào)試 React 最初的源碼呢?

于是,他跑來問我:光哥,你調(diào)試 React 源碼會有這些問題么?你是怎么調(diào)試的呀?

我說,確實(shí),我最開始也是調(diào)試的 react-dom.development.js,但是現(xiàn)在已經(jīng)能直接調(diào)試 React 最初的源碼了,而且是在 VSCode 里調(diào)試的,點(diǎn)擊調(diào)用棧能直接打開對應(yīng)的 React 源碼文件并定位到對應(yīng)行列號:

哇哦,這就是我想要的調(diào)試效果,這是怎么做到的呀。

想實(shí)現(xiàn)這樣的調(diào)試效果確實(shí)還有點(diǎn)復(fù)雜,我們一點(diǎn)點(diǎn)來看:

首先,我們要做到在 VSCode 里調(diào)試 React 項(xiàng)目,而不是在 Chrome Devtools 里,這樣才能做到直接打開對應(yīng)的文件:

用 VSCode 調(diào)試 React 項(xiàng)目

我們用 create-react-app 創(chuàng)建一個 react 項(xiàng)目,然后 npm run start 跑起來。

Chrome Devtools 調(diào)試

這時候?yàn)g覽器訪問就可以用 Chrome Devtools 調(diào)試了:

但我們的目標(biāo)是在 VSCode 里調(diào)試,所以要添加一個 VSCode 的 debugger 配置:

在根目錄下建一個 .vscode/launch.json 的文件,添加一個 chrome 類型的調(diào)試配置,輸入調(diào)試的 url。

然后點(diǎn)擊 debug 啟動:

這時候就可以在 VSCode 里直接打斷點(diǎn)調(diào)試了:

用 VSCode 調(diào)試肯定會比 Chrome Devtools 方便一些。但這不是我們最主要的目的,現(xiàn)在調(diào)試的依然是 react-dom.development.js:

那怎么調(diào)試 react 最初的源碼呢?

這就涉及到 sourcemap 的作用了:

sourcemap

JS 代碼經(jīng)過編譯,會產(chǎn)生目標(biāo)代碼,但同時也會產(chǎn)生 sourcemap。sourcemap 的作用就是映射目標(biāo)代碼中的位置和源碼中的位置。

比如源碼中的第 3 行第 5 列的代碼對應(yīng)著編譯后的第 1 行第 10 列的代碼。

類似這樣的映射有很多,經(jīng)過編碼以后是這樣的:

在 js 文件最后一行,加上這樣一行注釋就可以關(guān)聯(lián) sourcemap:

//# sourceMappingURL=http://example.com/path/to/your/sourcemap.map

調(diào)試工具支持解析 sourcemap 來映射調(diào)試的代碼位置到源代碼中的位置。

比如 chrome devtools 的 Sources 面板就會提示從哪個文件 source mapping 過來的,點(diǎn)擊鏈接還可以跳到映射之前的文件:

同樣,VSCode Debugger 也支持 sourcemap,有個 sourceMaps 的調(diào)試配置選項(xiàng)來開啟和關(guān)閉 sourcemap 功能,默認(rèn)開啟。

那這么說我們只要讓 react-dom.development.js 關(guān)聯(lián)上 sourcemap,就能調(diào)試最初的 React 源碼了?

理論上是這樣的,但是現(xiàn)在下載的 react、react-dom 包里都不帶 sourcemap,我們得把 React 源碼下載下來自己 build:

build 出帶有 sourcemap 的 react 包

npm 下載react包

用 npm 下載的 react 包是這樣的:

而我們需要的是帶有 sourcemap 的代碼,也就是這樣的:

這就要下載 react 源碼自己 build 了:

git clone https://github.com/facebook/react

下載下來的代碼執(zhí)行 npm run build 就能看到 build 的產(chǎn)物:

這里的 build/node_modules 下的 react 和 react-dom 包就是我們需要的。

但是現(xiàn)在 build 出的代碼并沒有帶 sourcemap,需要改造下 build 流程。

build 命令執(zhí)行的是 ./scripts/rollup/build.js,打開這個文件做一些修改。

找到 rollup 的配置,添加一行 sourcemap: true,這個很容易理解,就是讓 rollup 在構(gòu)建時產(chǎn)生 sourcemap:

再跑 npm run build,會報這樣的錯誤:

某個轉(zhuǎn)換的插件沒有生成 sourcemap。

這個是因?yàn)闃?gòu)建的過程中會進(jìn)行多次轉(zhuǎn)換,會生成多次 sourcemap,然后把 sourcemap 串聯(lián)起來就是最終的 sourcemap。如果中間有一步轉(zhuǎn)換沒有生成 sourcemap,那就斷掉了,也就沒法把 sourcemap 串聯(lián)起來了。

插件注釋

這個問題的解決只要找出沒有生成 sourcemap 的那幾個插件注釋掉就可以了:

在 getPlugins 方法里,把這樣 4 個插件給注釋掉:

這個是刪除 use strict 用的,可以去掉。

這個是生產(chǎn)環(huán)境壓縮代碼的,也可以去掉。

這個是用 prettier 格式化代碼的,也可以去掉。

這個是添加一些頭部的代碼的,比如 Lisence 等,也沒啥用,可以去掉。

去掉這四個插件之后,再運(yùn)行 npm run build,這時候就能正常進(jìn)行構(gòu)建了,然后產(chǎn)生的代碼就是帶有 sourcemap 的:

這樣我們就成功的 build 出了帶有 sourcemap 的 react 包!

調(diào)試 React 最初源碼

接下來只剩最后一步,用上 sourcemap,實(shí)現(xiàn)直接調(diào)試 React 最初的源碼,

應(yīng)用 sourcemap,調(diào)試 React 最初的源碼

我們已經(jīng) build 除了帶有 sourcemap 的 react 和 react-dom 包,那把這倆包復(fù)制到測試項(xiàng)目的 node_modules 下,就可以直接調(diào)試最初的源碼了么?

還是不行。

為什么呢?

看下面這張圖:

我們改造了 build 流程,對 react 源碼進(jìn)行了 build,產(chǎn)生了帶有 sourcemap 的 react、react-dom 包,這些包最終導(dǎo)出的是 react-xx.development.js。

之后在項(xiàng)目里引入,經(jīng)過 webpack 打包,產(chǎn)生了 bundle.js 和 sourcemap。

之后調(diào)試工具運(yùn)行代碼的時候,會解析 sourcemap,完成從 bundle.js 到 react-xxx.development.js 的映射:

但是并不會再次做 react-xx.development.js 到 react 最初源碼的映射呀。

也就是調(diào)試工具只會解析一次 sourcemap。

那怎么辦呢?

不打包 react 和 react-dom 這倆包不就行了。不經(jīng)過 webpack 打包,那就沒有 webpack 產(chǎn)生的 sourcemap,不就一次就映射到 React 最初的源碼了么。

那怎么不打包這倆模塊呢?

webpack 支持 externals 來配置一些模塊使用全局變量而不進(jìn)行打包,這樣我們就可以單獨(dú)加載 react、react-dom,然后把他們導(dǎo)出的全局變量配置到 externals 就行了。

要改動 webpack 配置的話,在 create-react-app 下要執(zhí)行 npm run eject。

然后項(xiàng)目下會多出 config 目錄和 public 目錄,這倆分別放著 webpack 配置和一些公共文件。

修改 webpack 配置,在 externals 下添加 react 和 react-dom 包對應(yīng)的全局變量:

然后把 react.development.js 和 react-dom.development.js  放到 public 下,并在 index.html 里面加載這倆文件:

這樣再重新 debug,你就會發(fā)現(xiàn) sourcemap 映射到 React 最初的源碼了:

不再是 react-dom.development.js 下的代碼,而是具體 react-xxx 包下的。

這就達(dá)到了最開始的目的,能直接調(diào)試 React 最初的源碼!

還記得我們這樣做的意義么?

能調(diào)試最初的源碼才能知道哪段邏輯是在哪個包里的,不然要自己去搜索。

這樣已經(jīng)能夠達(dá)到我們的目的了,但是要想點(diǎn)擊調(diào)用棧直接定位到 git clone 下來的 react 項(xiàng)目的文件,還需要再做一步。

關(guān)聯(lián) react 源碼項(xiàng)目

看我最初演示的效果,點(diǎn)擊調(diào)用棧是能直接定位到 react 源碼項(xiàng)目的文件的:

這是怎么做到的呢?

其實(shí)只要 sourcemap 生效,并且 map 到的文件是在當(dāng)前 workspace 下,VSCode 就會打開對應(yīng)的文件。

現(xiàn)在 sourcemap 已經(jīng)生效了,只不過 react 項(xiàng)目沒有在 workspace 下。所以,如果想直接定位 react 源碼項(xiàng)目的話,可以這樣做:

創(chuàng)建一個新的目錄,把 react 源碼項(xiàng)目和測試的項(xiàng)目放到一個 workspace 下,這樣再調(diào)試的時候,map 到的文件就能在 workspace 找到了,也就會打開相應(yīng)的文件。

只不過現(xiàn)在 sourcemap 下都是這樣的相對路徑,會導(dǎo)致映射到的文件路徑不對:

所以再去修改下 react build 流程,在 ./script/rollup/build.js 下,添加一個 sourcemap 的路徑映射,把 ../../../packages 映射到 react 項(xiàng)目的絕對路徑/pcakges :

這時候再重新 build,生成的 sourcemap 就是絕對路徑了:

把新生成的 sourcemap 復(fù)制過去,覆蓋一下。

在新的 workspace 里 debug,你就會發(fā)現(xiàn),路徑映射對了:

點(diǎn)擊調(diào)用棧能直接打開 react 源碼項(xiàng)目的對應(yīng)文件了!

至此,我們就能優(yōu)雅的調(diào)試 React 最初的源碼了。

總結(jié)

用了 react 比較長時間后,自然會想調(diào)試下源碼來深入下,但是常規(guī)的調(diào)試方式只能調(diào)試 react-dom.development.js,雖然能理清邏輯,但是對應(yīng)不到源碼里的哪些包哪些文件,總感覺和最初的源碼還有一段距離。

這個問題是有解決方案的,就是會有點(diǎn)復(fù)雜:

首先要把 react 源碼項(xiàng)目下載下來,修改 build 流程來生成帶有 sourcemap 的 react 和 react-dom 包,并且修改 sourcemap 映射的路徑為絕對路徑。

然后把 react 和 react-dom 配置到 webpack 的 externals 里,不進(jìn)行打包,而是單獨(dú)在 index.html 里引入。

因?yàn)?sourcemap 只會映射一次,而 webpack 已經(jīng)生成了一次 sourcmap,只有跳過這倆模塊的打包才能讓 react 和 react-dom 的 sourcemap 生效。

之后用 VSCode Debugger 來調(diào)試 React 項(xiàng)目,就能映射到最初的 React 源碼了。

如果想點(diǎn)擊調(diào)用棧直接打開對應(yīng) React 源碼項(xiàng)目的文件,那就新建一個 workspace,把測試項(xiàng)目和 React 源碼項(xiàng)目包含就行了。因?yàn)?VSCode 如果在 workspace 下找到了 source map 到的文件,就會直接打開對應(yīng)的文件。

東東:最終的調(diào)試效果是很完美,但這個流程有點(diǎn)復(fù)雜

我:確實(shí),想實(shí)現(xiàn)能調(diào)試最初的源碼,并且還能直接打開對應(yīng)的 react 源碼項(xiàng)目的文件,還是比較麻煩的,但好在只需要配置一次,以后就能一直用了,而且類似的源碼調(diào)試方式也可以應(yīng)用到其他源碼的調(diào)試。

毫不夸張地說,這應(yīng)該是全網(wǎng)最優(yōu)雅的 React 源碼調(diào)試方式了。

以上就是React 源碼調(diào)試方式的詳細(xì)內(nèi)容,更多關(guān)于React 源碼調(diào)試的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React事件節(jié)流效果失效的原因及解決

    React事件節(jié)流效果失效的原因及解決

    這篇文章主要介紹了React事件節(jié)流效果失效的原因及解決,幫助大家更好的理解和學(xué)習(xí)使用React框架,感興趣的朋友可以了解下
    2021-04-04
  • ReactNative實(shí)現(xiàn)的橫向滑動條效果

    ReactNative實(shí)現(xiàn)的橫向滑動條效果

    本文介紹了ReactNative實(shí)現(xiàn)的橫向滑動條效果,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),補(bǔ)充介紹了ReactNative基于寬度變化實(shí)現(xiàn)的動畫效果,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • react如何同步獲取useState的最新狀態(tài)值

    react如何同步獲取useState的最新狀態(tài)值

    這篇文章主要介紹了react如何同步獲取useState的最新狀態(tài)值問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 使用React18和WebSocket構(gòu)建實(shí)時通信功能詳解

    使用React18和WebSocket構(gòu)建實(shí)時通信功能詳解

    WebSocket是一種在Web應(yīng)用中實(shí)現(xiàn)雙向通信的協(xié)議,它允許服務(wù)器主動向客戶端推送數(shù)據(jù),而不需要客戶端發(fā)起請求,本文將探索如何在React?18應(yīng)用中使用WebSocket來實(shí)現(xiàn)實(shí)時通信,感興趣的可以了解下
    2024-01-01
  • 一文帶你搞懂useCallback的使用方法

    一文帶你搞懂useCallback的使用方法

    useCallback是用來幫忙緩存函數(shù)的,當(dāng)依賴項(xiàng)沒有發(fā)生變化時,返回緩存的指針,而props涉及到復(fù)雜對象類型都是通過指針來傳遞到,下面這篇文章主要給大家介紹了關(guān)于useCallback使用的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • 詳解React中的todo-list

    詳解React中的todo-list

    這篇文章主要介紹了React中的todo-list的相關(guān)知識,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-07-07
  • 使用ES6語法重構(gòu)React代碼詳解

    使用ES6語法重構(gòu)React代碼詳解

    本篇文章主要介紹了使用ES6語法重構(gòu)React代碼詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 關(guān)于React Native 無法鏈接模擬器的問題

    關(guān)于React Native 無法鏈接模擬器的問題

    許多朋友遇到React Native 無法鏈接模擬器的問題,怎么解決呢,本文給大家分享完整簡便解決方法及配置例題,對React Native 鏈接模擬器相關(guān)知識感興趣的朋友一起看看吧
    2021-06-06
  • React高級指引之Refs and the DOM使用時機(jī)詳解

    React高級指引之Refs and the DOM使用時機(jī)詳解

    在典型的React數(shù)據(jù)流中,props是父組件與子組件交互的唯一方式。要修改一個子組件,你需要使用新的props來重新渲染它。但是,在某些情況下,你需要在典型數(shù)據(jù)流之外強(qiáng)制修改子組件
    2023-02-02
  • React Hooks之使用useCallback和useMemo進(jìn)行性能優(yōu)化方式

    React Hooks之使用useCallback和useMemo進(jìn)行性能優(yōu)化方式

    這篇文章主要介紹了React Hooks之使用useCallback和useMemo進(jìn)行性能優(yōu)化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06

最新評論