我是如何閱讀原始碼的

語言: CN / TW / HK

最近寫了很多原始碼分析相關的文章,React、Vue 都有,想把我閱讀原始碼的一些心得分享給大家。

React:

Vue:

快速除錯原始碼

說到看原始碼,很多人都有個誤區,覺得看原始碼必須要到 github 上把完整的程式碼 clone 下來,認為只有把完整的程式碼下載下來,才能開始愉快的學習。

除錯 React

這裡我們先拿 React 舉例,把原始碼 clone 下之後,整個人都懵逼了。

git clone [email protected]:facebook/react.git
複製程式碼

React 原始碼目錄解構

一般這時候會開始在網上搜文章,如何除錯 React 原始碼。但是這種大型專案的構建流程較為複雜,如果只是想簡單瞭解原始碼,不需要去了解這些複雜的東西。這裡教大家一個簡單的方案,直接到 CDN 上下載官方編譯好了的開發版原始碼(cdn.jsdelivr.net/npm/react@1…),中間的版本號可以替換成任何想看的版本。

react

有了原始碼之後,我們要開始寫 Demo,這時候如果自己搭一個專案就比較麻煩了,因為寫 React 就會有 jsx,就需要 babel 進行 jsx 轉義,這裡推薦使用官方腳手架: create-react-app

npx create-react-app react-demo
cd react-demo
複製程式碼

這裡我們需要稍微修改下 webpack 的配置,通過 react-app-rewired 修改配置。

npm install react-app-rewired --save-dev
複製程式碼

修改package.json

然後,在資料夾內新建 config-overrides.js 檔案,配置 webpack 的 externals 屬性,讓專案內的 react、react-dom 都能夠走 window 下掛載的物件。

/* config-overrides.js */

module.exports = function override(config, env) {
  // do stuff with the webpack config...
  config.externals = {
    'react': 'window.React',
    'react-dom': 'window.ReactDOM',
  };
  return config;
}
複製程式碼

接下就是將 react 掛載到 window 上,把我們之前在 CDN 上下載的 develope 版的原始碼放到 public 目錄,然後在 public/index.html 中引入原始碼。

全域性引入 react

然後通過 npm run start 正常啟動專案就好了。

React App

接下來就能愉快的搞事情,可以在 Chrome 的 Sources 面板裡面開始 debug 之旅了,當然如果你更喜歡 console.log ,也可以在 public/react.js 裡打上心愛的 log 。

Sources

除錯 Vue

除錯 Vue 比 React 更加簡單,因為 Vue 支援瀏覽器進行模板編譯。我們同樣在 CDN 直接下載已經編譯好的完整開發版(www.jsdelivr.com/package/npm…)。

image-20201205232605725

然後,新建一個 vue.html ,把檔案丟到本地的 http 服務裡面。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue3 Demo</title>
</head>
<body>
  <div id="app"></div>
  <script src="/script/vue3.js"></script>
  <script>
    const app = Vue.createApp({
      data() {
        return {
          name: 'shenfq'
        }
      },
      template: `<div> Vue App </div> `
    })
    app.mount('#app')
  </script>
</body>
</html>
複製程式碼

我們現在已經可以直接開始除錯 Vue3 的原始碼了,就是這麼簡單粗暴。當然,如果想通過 .vue 的方式寫模板,還是得參照上面 React 提到的那種方式。

找準切入點

有了除錯原始碼的方法,我們還需要找準一個切入點,不能為了看原始碼而看原始碼。所謂的切入點就是一個個小問題,比如我想要弄懂 Vue 的模板是如何轉變成虛擬 DOM 的,我們可以先在官方文件查詢資料,看有沒有相關說明,幸運的是,Vue 官方文件在渲染函式-模板編譯部分剛好這個問題有相關說明。

Vue官方文件

文件中提到了 Vue.compile ,然後我們就可以在原始碼中搜索這個 Api 開始進行除錯。這就是帶著目的去看原始碼,我們只有帶著問題出發的時候,才會具有更高的效率。

除了帶著問題出發,還可以參考其他優秀的文章,集千萬網友的智慧於一體。當然這也是個雙刃劍,因為你可能會搜到一些辣雞文章,反而降低你的效率。而且,框架在迭代的過程中,變化會很多,可能你學習的是 React 16 的原始碼,搜到的 React 15 相關的文章,然後你會花很多時間和精力想去弄清楚為什麼你看到的和別人寫的為什麼不一樣,到底是你的開啟方式不對,還是作者有筆誤。

同時,還有一些文章喜歡畫一些吸引眼球的架構圖(我本人),看完你會直呼內行,但是這些架構圖大多是站在作者個人的角度上的畫的,很可能和你之前的角度不一樣,又需要花一些時間來理解他的思路。如果,我們把龐大的專案拆分成一個個小小的問題之後,逐個擊破,這時候再從全域性的角度來思考整個框架的設計思路以及執行邏輯,就能事半功倍。

強制輸出

有輸出的學習才是學習,在閱讀原始碼的過程中,一定得邊看邊思考,思考的過程中,還需要形成文字記錄,如果只是一直盯著程式碼看,很難理解。

我在看原始碼的過程中,會一直思考,怎麼樣才能將這部分講給別人聽,是不是能寫個 Demo 之類的,讓大家跟著我的思路來學習。這樣即讓自己學懂了,又可以將學習的過程分享出來幫助到其他人,何樂而不為。