新聞中心
??上篇文章??寫了怎么調試 antd 的源碼,反響很不錯:

但很多小伙伴是寫 Vue 的,可能平時用的是 Element UI 的組件庫,所以這篇文章就來講下怎么調試 Element UI 的源碼。
首先,我們用 Vue CLI 創(chuàng)建一個 vue2 的項目:
yarn global add @vue/cli
vue create element-vue-test
創(chuàng)建成功后,進入到項目目錄
安裝 element ui 的庫,并在入口引入:
然后在 App.vue 里用一下 button 組件
之后 yarn run serve 把開發(fā)服務跑起來,就可以看到這樣的頁面:
Element UI 的組件正確的顯示了。
接下來調試 button 組件的源碼,那問題來了,我怎么知道在哪里打斷點呢?
我們可以知道的是,這個 button 會處理點擊事件,但是卻不知道事件處理函數(shù)的代碼在什么地方。
這種情況可以加一個事件斷點:
在 sources 面板的 Event Listener Breakponts 里勾選 Mouse 的 click 事件,也就是在所有 click 事件的處理函數(shù)處斷住。
然后你再點下那個按鈕試試看:
你會發(fā)現(xiàn)它在事件處理函數(shù)處斷住了。
當你知道這個組件處理了什么事件,但卻不知道事件處理函數(shù)在哪的時候就可以用事件斷點。
當然,這個事件處理函數(shù)并不是組件里的,因為 Vue 內部會先做一些處理,然后再交給組件處理。
所以,我們要先走到組件的事件處理函數(shù):
單步執(zhí)行、再進入函數(shù)內部,再單步執(zhí)行、再進入函數(shù)內部,代碼就會走到組件的事件處理函數(shù):
methods、computed、props,這明顯是源碼里的了。但你再往上走兩步,會發(fā)現(xiàn)又不是最初的源碼:
template 變成了 render 函數(shù),而且還有其他組件的代碼,這明顯是被編譯打包之后的代碼。
從文件名也可以看出來:
這是一個把所有組件代碼編譯后打包到一起的文件。
這樣雖然也能調試,但肯定是不爽的,能不能直接調試組件最初的源碼呢?就是帶 template 的單文件組件那種?
是可以的,這就要用到 sourcemap 了。
sourcemap 是在編譯過程中產(chǎn)生的:
里面記錄了目標代碼和源代碼的映射關系,調試的時候可以通過它映射回源碼:
但是你去 node_modules 下看看,會發(fā)現(xiàn)沒有這個文件的 sourcemap:
那怎么生成它的 sourcemap 呢?
這就要從源碼重新編譯了。
我們從 github 把它的源碼下載下來:
git clone --depth=1 --single-branch git@github.com:ElemeFE/element.git
--depth=1 是只下載單個 commit,--single-branch 是下載單個 branch,這樣下載速度能快幾十倍,是一個加速小技巧。
進入 element 目錄,安裝依賴,你會遇到一個前端經(jīng)常頭疼的問題,node-sass 安裝報錯了:
這個問題的解決方案就是把 node 版本切換到 node-sass 版本對應的那個。
package.json 中可以看到 node-sass 是 4.11.0
打開 node-sass 的 github 首頁:
你會看到這樣一個版本對應關系表:
4.11 對應 node11,那就把 node 切換到 11 就可以了。
然后再次 yarn 安裝依賴就能成功了。
之后開始編譯,在 npm scripts 中可以找到 dist 命令,這就是構建源碼用的:
但是我們只需要 element-ui.common.js 這個文件:
其實只需要執(zhí)行其中的一部分腳本,也就是這個:
所以在項目下執(zhí)行 npx webpack --config build/webpack.common.js 即可:
然后在 lib 下就可以看到構建產(chǎn)物:
但我們的目標是生成帶有 source-map 的代碼,所以要改下配置:
修改 build/webpack.common.js,配置 devtool 為 cheap-module-source-map:
source-map 是生成 sourcemap 并關聯(lián),也就是這樣:
module 是把中間 loader 產(chǎn)生的 sourcemap 也給合并到最終的 sourcemap 里,這樣才能直接映射到源碼。
cheap 是加快編譯速度用的,只保留行的映射信息。
改完配置后再次 yarn run dist,就可以看到帶有 sourcemap 的產(chǎn)物了:
把這倆文件復制到測試項目的 node_modules/element-ui 下覆蓋下之前的:
之后清掉 node_modules/.cache 下的緩存,重新跑 dev server:
這時會報錯提示你 node 版本太低了,你需要再把 node 版本換回來:
跑起開發(fā)服務之后,再次用之前的方式調試 button 組件的源碼:
你會發(fā)現(xiàn)現(xiàn)在的組件代碼是帶 template 語法的單文件組件的代碼了!
這就是 sourcemap 的作用。
之后你會可以在這個組件里打斷點然后調試。
有的同學可能會問,通過事件斷點進入組件內部,這樣有點麻煩,有沒有更簡單的方式?而且 button 組件有點擊事件,但有的組件沒有呀,這些組件該怎么調試呢?
確實,有了 sourcemap 之后就有更簡單的調試方式了。
你可以在 sources 左邊看到 ELEMENT 目錄下有很多 vue 文件,這其實就是 Chrome DevTools 解析 sourcemap 之后列在這里的:
你可以直接在里面打斷點調試。
比如我們加一個 tabs 組件:
把前面添加的那個事件斷點去掉,在代碼里手動打一個斷點:
然后你就會發(fā)現(xiàn),這樣就可以調試 Element UI 組件源碼了!
當然,有的組件找不到的時候,還是可以通過事件斷點的方式來進入組件內部。
我們是通過 Chrome DevTools 調試的,其實用 VSCode Debugger 來調試它也是一樣的,在 Chrome DevTools 里打的斷點,在 VSCode Debugger 里同樣會斷住。
總結
今天我們調試了 Element UI 的源碼。
定位到組件的代碼,是通過事件斷點的方式,因為我們知道它觸發(fā)了什么事件,但卻不知道事件處理函數(shù)在哪。
但是組件的代碼是被編譯打包過的,不是最初的源碼。
為了調試最初的源碼,我們下載了 Element UI 的代碼,build 出了一份帶有 sourcemap 的代碼。
覆蓋項目 node_modules 下的代碼,重新跑 dev server,這時候就可以直接調試組件源碼了。
有了 sourcemap 之后,Chrome DevTools 會直接把 vue 文件列在 sources 里,我們可以找到對應的 vue 文件來打斷點,就不用通過事件斷點來找了。
能夠調試 Element UI 源碼之后,想知道組件內部都有哪些邏輯的話,就可以直接在源碼斷點調試了,就很香。
網(wǎng)站名稱:我是怎么調試ElementUI源碼的
標題來源:http://www.dlmjj.cn/article/dpsoosd.html


咨詢
建站咨詢
