天天看點

幹貨|如何去閱讀大型前端項目的源碼?

作者:架構師成長曆程

目前網上有很多「XX源碼分析」這樣的文章,不過這些文章分析源碼的範圍有限,有時候講的内容不是讀者最關心的。同時我也注意到,源碼是在不斷更新的,文章裡寫的源碼往往已經過時了。因為這些問題,很多同學都喜歡自己看源碼,自己動手,豐衣足食。

這篇文章主要講的是讀大型的前端開源項目比如 React、Vue、Webpack、Babel 的源碼時的一些技巧。目的是讓大家在遇到需要閱讀源碼才能解決的問題時,可以更快的定位到自己想看的代碼。授人以魚不如授人以漁,希望大家可以通過這篇部落格,了解到閱讀大型前端項目源碼時的切入點。在之後遇到好奇的問題時,可以自己去探索。

這篇文章我準備來聊一聊如何去閱讀開源項目的源碼。

在聊如何去閱讀源碼之前,先來簡單說一下為什麼要去閱讀源碼,大緻可分為以下幾點原因:

  • 最直接的原因,就是面試需要,面試喜歡問源碼,讀完源碼才可以跟面試官battle
  • 提升自己的程式設計水準,學習程式設計思想和和代碼技巧
  • 熟悉技術實作細節,提高設計能力
  • ...

那麼到底該如何去閱讀源碼呢?這裡我總結了18條心法,助你修煉神功

幹貨|如何去閱讀大型前端項目的源碼?

學好JDK

身為一個Javaer,不論要不要閱讀開源項目源碼,都要學好JDK相關的技術。

所有的Java類開源項目,本質上其實就是利用JDK已有的類庫和關鍵字實作一種業務功能,是以學會了JDK相關的類庫是看其它的源碼基礎。

如果你不懂JDK,你去閱讀源碼會發現有太多看不懂的地方,會影響讀源碼的心情和信心。

學習JDK主要包括使用和原理兩部分。内容大緻包括以下幾部分:

  • 集合相關,比如常見的Map,List,Queue的實作,包括線程安全與不安全
  • 并發相關,比如synchronized、volatile、CAS、AQS、鎖、線程池、原子類等等
  • io相關,包括bio和nio等等
  • 反射相關
  • 網絡程式設計相關
  • ...

了解設計模式

在一個優秀的開源項目中,設計模式處處存在,是以在你開始閱讀源碼之前最好先了解一下常見的一些設計模式。當你了解了一些設計模式以後,在源碼中遇到了相關的設計模式,你就可以快速明白代碼結構的設計,進而以整體的視角去閱讀相關代碼。

同時,學習設計模式不僅可以幫助我們閱讀源碼,在日常開發中也可以幫助我們設計出更易于擴充的程式。

學習設計模式的話可以看看《大話設計模式》這本書,如果不想看書也可以找一些視訊或者專欄。

之前我也寫過一篇關于開源項目中常用的設計模式文章 兩萬字盤點那些被玩爛了的設計模式 ,有興趣的小夥伴可以看看。

先從官網入手

官網是介紹開源項目的地方,同時也是學習一個開源項目最開始的地方,通過官網我們可以快速的了解項目,比如:

  • 項目的定位
  • 一些核心概念
  • 功能
  • 使用教程
  • 整體的架構和設計
  • 常見的問題及解答
  • ...
幹貨|如何去閱讀大型前端項目的源碼?

RokcetMQ官網

當你了解了項目的一些概念、功能等資訊之後,如果你在讀源碼一旦發現了代碼是實作這些概念或者功能的足迹,那麼能夠幫助你更好的了解代碼。

熟悉源碼子產品結構

當你對項目有大緻的了解之後,就可以從Github上把代碼clone下來,官網有項目源碼的Github位址。

當成功拉下來代碼之後,就可以對項目源碼子產品進行簡單的分析,熟悉子產品結構,分析子產品功能,混個眼熟。

幹貨|如何去閱讀大型前端項目的源碼?

如上是RocketMQ源碼,如果前面閱讀過官網相關的一些概念介紹,就大緻可以知道這些子產品有什麼功能。

幹貨|如何去閱讀大型前端項目的源碼?

RocketMQ概念介紹

比如說,源碼中的broker子產品,官網說broker主要是負責消息存儲,那麼broker子產品代碼塊肯定就主要實作了消息存儲的功能。

還有些子產品可以根據單詞的意思進行判斷,比如common子產品,一看就是存儲一些公共類的子產品,example子產品,就是RocketMQ使用代碼示例的子產品等等。

順着demo開始讀

有的小夥伴在讀源碼的時候不知道從哪裡開始讀比較合适,最後随便從源碼中的某個子產品就開始讀,讀讀越來越發現讀不下去。

讀源碼正确的姿勢應該是從demo開始讀。

比如說,現在我想要閱讀一下RocketMQ生産者是如何發送消息的,整個過程是什麼樣的,那麼我首先至少得寫個發送消息的demo,看看代碼是如何寫的。

demo一般可以從官網中檢視

幹貨|如何去閱讀大型前端項目的源碼?

RocketMQ官網發送消息代碼示例

除了官網,一般開源項目在源碼中也會有相應的demo,代碼放在示例子產品,就比如上面提到的RocketMQ的example子產品。

最後還可以通過谷歌搜尋一下demo。

DefaultMQProducer producer = new DefaultMQProducer("sanyouProducer");
//指定NameServer的位址
producer.setNamesrvAddr("localhost:9876");
//啟動生産者
producer.start();
//省略代碼。。
Message msg = new Message("sanyouTopic", "TagA", "三友的java日記".getBytes(RemotingHelper.DEFAULT_CHARSET));
// 發送消息并得到消息的發送結果,然後列印
SendResult sendResult = producer.send(msg);
           

如上是RocketMQ生産者發送消息的一個demo,消息發送源碼閱讀就從這塊代碼開始入手,一步一步進入源碼中,這就算開始閱讀源碼了。

帶着目的去讀

帶着目的去讀其實很好了解,就拿上面生産者發送消息流程源碼來說,讀源碼的第一個目的其實就是弄懂生産者發送消息的流程。

除了弄懂生産者發送消息,你還可以帶着其它目的去讀。

比如說,消息發送的核心邏輯是send方法實作的,那麼除了消息發送,是不是可以去弄懂生産者在啟動的過程做了哪些事,也就是start方法的作用。

再比如生産者發送消息肯定涉及到網絡通信相關的内容,那麼了解RocketMQ底層網絡通信模型是不是也可以算一個目的。

當你帶着這些目的,你讀源碼就有很強的目的性,讀完印象會很深刻。當然如果你最開始想不到這些目的,也沒有什麼關系,你可以先往下讀,在讀的過程中再去嘗試發現一些其它的目的。

先抓主線,再抓分支

有的小夥伴在讀源碼的時候,每個方法都使勁一直往下點,最後都不知道代碼進入到哪了,這其實是非常不可取的。

正确的方法應該是先抓住主線流程,分支流程先大緻看看,知道大概是什麼作用,等讀完主線之後,再回過頭仔細讀一下分支代碼。

舉個例子來說,在Spring中,ApplicationContext在使用之前需要調用一下refresh方法,而refresh方法就定義了整個容器重新整理的執行流程代碼。

幹貨|如何去閱讀大型前端項目的源碼?

refresh方法部分截圖

當在讀這段代碼,你可以先讀一讀refresh中各個方法大緻都做了什麼,等讀完之後,你可以具體的去讀每個代碼的具體實作,比如說prepareRefresh幹了什麼,obtainFreshBeanFactory是如何擷取到BeanFactory的,prepareBeanFactory又在對BeanFactory做了什麼事等等。

不要過度摳實作細節

有的小夥伴在閱讀的時候特别喜歡深究,想要弄清每行代碼是如何實作的,這不僅非常難而且也是不可取的。

就比如說,我們都知道,在Spring Bean的生命周期中,當存在基于xml的方式來聲明Bean的方式,Spring會去解析xml,生成BeanDefinition。當你想要了解Bean的生命周期過程的時候,其實是沒有太大的必要去過度扣Spring是如何解析xml生成BeanDefinition的細節,這對你整體了解Bean的生命周期沒有太大的意義,隻需要知道最終會轉換成BeanDefinition就可以了。

那什麼時候去扣實作細節呢?

  • 當你需要使用到的時候,比如說你遇到了一個bug或者是需要擴充
  • 阻礙你了解功能實作的時候

大膽猜

讀源碼的時候也需要我們發揮一點想象力,去猜一猜功能是如何實作的。猜不是瞎猜,而是基于目前了解的一些知識、技術或者是思想合理地去猜。

就比如說,當你已經知道了OpenFeign最終會對每一個FeignClient接口生成動态代理對象,之後注入的對象都是代理對象,代理對象中實作了RPC的請求之後,那麼當你在學習dubbo的時候,是不是就可以去猜測注入的dubbo接口最終也是一個動态代理對象,并且這個代理對象也實作了RPC的請求?

之後你在讀代碼的時候就需要着重注意發現是否有動态代理生成的代碼,這就算是一個目的,一旦發現了動态代理相關的代碼,那麼這塊代碼很可能就是dubbo RPC實作的核心。

學會看類名

不要小看類名,優秀的代碼命名都是見名知意的,是以從類名也可能窺探出這個類的一些蛛絲馬迹。

如下列舉了幾個比較常用的命名習慣

  • 以Registry結尾的一般都是存儲功能,比如Spring中的SingletonBeanRegistry就是用來儲存單例Bean的;Mybatis中的MapperRegistry就是用來儲存Mapper接口的
  • 以Support、Helper、s、Util(s)結尾的一般都是工具類
  • 以Filter,Interceptor結尾的一般都是攔截作用,一般會配合責任鍊模式(Chain)使用
  • 以Event、Listener結尾的一般都是基于觀察者模式實作的事件釋出訂閱模型
  • ...

除了一些比較通用的命名習慣,也有一些項目獨有的一些命名習慣。

比如說Spring中常見的以PostProcessor結尾的都是擴充接口,實作這些接口可以拿到某個比較核心的元件,進而實作對Spring的擴充。

其實很多開源項目的命名都比較偏向Spring的命名風格,當你遇到了跟Spring的命名比較像的時候,那麼可以大膽猜測類的作用。

學會看類結構

類結構也非常重要,他也能夠幫助我們窺探類的大緻功能。

幹貨|如何去閱讀大型前端項目的源碼?

ApplicationContext

如上圖,是Spring中ApplicationContext的繼承體系,當你需要了解ApplicationContext的時候,可以先去熟悉一下它的父接口的作用,當你大緻弄明白了每個接口的作用,那麼ApplicationContext有啥作用就大緻就清楚了。

除了可以看類繼承體系,還可以浏覽一下類大緻提供了哪些方法,了解對外提供的功能。

類方法通過快捷鍵 ctrl+F12(mac:fn+command+F12)檢視,并且還支援模糊搜尋方法名,我本人就非常喜歡這個快捷鍵

幹貨|如何去閱讀大型前端項目的源碼?

ApplicationContext

總結類的職責

當我們在讀完一個類的代碼的時候,一定要總結這個類的職責,明白這個類存在的意義。一般情況下一個類核心職責隻有一個,遵循單一職責的設計原則。

舉個例子,在RocketMQ中有一個類MQClientAPIImpl

幹貨|如何去閱讀大型前端項目的源碼?

MQClientAPIImpl

其實從名字大概看不出這個類主要是有什麼功能,但是當我讀代碼的時候發現每個方法最終都調用RemotingClient方法,而RemotingClient隻有一個實作NettyRemotingClient,是以從這個實作和類名可以猜出來RemotingClient是發送網絡請求的用戶端,是以當讀完MQClientAPIImpl源碼之後,我就知道了MQClientAPIImpl這個類的職責大緻是封裝參數,然後通過RemotingClient向MQ發送消息的。

當知道這個類的職責的時候,那麼其它地方在調用這個類的方法的時候,就知道大概在做什麼事了。

習慣閱讀注釋

當你在讀源碼的時候,如果有注釋,最好能先讀一下注釋,這樣能幫助你厘清類或者方法的功能,先知道功能,再去讀源碼就容易多了。

注釋一般都是英文,如果看不懂,可以裝個插件

幹貨|如何去閱讀大型前端項目的源碼?

寫好注釋

俗話說的好記性不如爛筆頭,寫好注釋也是閱讀源碼中很重要的一個環節,好的注釋可以幫助快速回憶起實作細節和功能。

注釋并不需要對每行代碼都注釋,當然如果你願意也沒多大問題,但是注釋應包括以下幾點内容:

  • 核心類和方法實作的核心功能
  • 核心功能大緻的實作邏輯
  • 核心的成員變量的作用
  • 方法中不易讀懂的代碼實作細節
幹貨|如何去閱讀大型前端項目的源碼?

DefaultMessageStore

如圖,是我讀RocketMQ中對于DefaultMessageStore類閱讀的注釋,這個類是RocketMQ中一個非常核心的類,從名字可以看出來跟消息的存儲有關。這個類的功能非常多,是以我寫了很多注釋,列舉了這個類主要有哪些功能和這些功能實作的一些細節。

總結思想,及時輸出

當你讀完某個功能子產品的時候,就可以嘗試對這塊功能實作邏輯或者思想進行總結。

比如說,當你了解了CAS思想的時候,你會發現,原來保證線程安全不僅僅可以通過加鎖的方式,還可以基于樂觀鎖的方式來實作。

在總結之後可以輸出成一個文檔,又或者是流程圖。我個人比較喜歡畫圖,這裡推薦兩個線上畫圖工具:

  • processon
  • draw.io

processon我平時就在用,功能多,但是需要收費;draw.io的話免費,圖示和顔色感覺比processon好看,平時文章中的貼圖就是用draw.io畫的。

這裡多說一句,總結思想還是非常重要的,在我閱讀了很多源碼之後,我發現很多技術或者功能的實作原理最終都是殊途同歸。

提前了解依賴的技術

一般一個開源項目不是所有的技術都是自己實作的,它也會依賴一些其它的架構或者是思想,提前了解這些架構或者是思想,可以幫助你更好地閱讀和理清代碼。

比如說,RocketMQ底層是基于Netty架構實作網絡通信的,當你對Netty有所了解,知道Netty在啟動的時候需要注冊一堆ChannelHandler用來處理網絡請求,那麼在讀RocketMQ底層網絡通信功能的時候你就可以去找一下Netty啟動的代碼,看看都注冊了哪些ChannelHandler,然後就知道RocketMQ是如何處理和發送請求的。

查閱相關資料

當在閱讀源碼的時候,對某一塊代碼功能實作不太清楚的時候,可以通過查閱相關資料來輔助閱讀,包括但不限于以下幾種通道:

  • 官網
  • 書籍
  • Github
  • 文章
  • 視訊

問題驅動——不要為了看源碼而看源碼

首先我們要明确一點,看源碼的目的是什麼?

我個人的意見是,看源碼是為了解決問題。開源項目的源代碼并沒有什麼非常特殊的地方,也都是普通的代碼。這些代碼的數量級一般都挺大,如果想是從源碼中學到東西,直接浏覽整個 Codebase 無疑是大海撈針。

但如果是帶着問題去看源碼,比如想了解一下 React 的合成事件系統的原理,想了解 React 的 setState 前後發生了什麼,或者想了解 Webpack 插件系統的原理。也有可能是遇到了一個 bug,懷疑是架構/工具的問題。在這樣的情況下,帶着一個具體的目标去看源碼,就會有的放矢。

看最新版的源碼

之前看到一種說法,看源碼要從項目的第一個 commit 開始看。如果是為了解決前文中對架構/工具産生的困惑,那自然要看目前項目中用到的架構/工具的版本。

如果是為了學習源碼,我也建議看最新的源碼。因為一個項目是在不斷疊代和重構的。不同版本之間可能是一次完全的重寫。比如 Vue 2.x 和 React 16。重構導緻了代碼架構上的一些變化,Vue 2.x 引入了 Vritual DOM,Pull + Push 的資料變化檢測方式讓整個代碼的結構變的更清晰了,是以 2.x 的代碼其實比 1.x 的更容易閱讀。React 16 重寫了 Reconciler,引入了 fiber 這個概念,整個代碼倉庫結構也更清晰,是以更推薦閱讀。

前置條件

看源碼怎麼看,當然不能一把梭了。

幹貨|如何去閱讀大型前端項目的源碼?

看源碼之前需要對項目的原理有一個基本的了解。所謂原理就是,這個項目有哪些組成部分,為了達到最終的産出,要經過哪幾步流程。這些流程裡,業界主流的方案有哪幾種。

比如前端 View 層架構,要渲染出 UI,元件要經過 mount、 render 等等步驟。資料驅動的前端架構,在 mounted 之後,就會進入一個循環,當使用者互動觸發元件資料變化時,會更新 UI。其中資料的檢測方式又有分 Push 和 Pull 兩種方案。渲染 UI 可以是全量的字元串模闆替換,也可以是基于 Virtual DOM 的差量 DOM 更新。

又比如前端的一些工具,Webpack 和 Babel 這些工具都是基于插件的。基本的工作流程就是讀取檔案,解析代碼成 AST,調用插件去轉換 AST,最後生成代碼。要了解 Webpack 的原理,就要知道 Webpack 基于一個叫 tapable 的子產品系統。

那我們要如何了解這些呢?要了解這些,可以去各大網站和部落格上的《XXX源碼解析》系列。通過這些文章,我們可以對我們要看的架構/工具的原理有一個大緻的了解。

本地build

不過最終我們還是要直接看源碼。筆者真正看源碼的第一步就是把項目的代碼倉庫 clone 到本地。然後按項目 README 上的建構指南,在本地 build 一下。

如果是前端架構,我們可以在 HTML 中裡直接引入本地 build 出的 umd bundle(記得用 development build,不然會把代碼壓縮,可讀性差),然後寫一個簡單的 demo,demo 裡引入本地的 build。如果是基于 Nodejs 的工具,我們可以用 npm link 把這個工具的指令 link 到本地。也可以直接看項目的 package.json 的入口檔案,直接用 node 運作那個檔案。

這裡要強調一下,大型的開源項目一般都會有一個 Contribution Guide,目的是讓想貢獻代碼的開發者更快上手。裡面就有講怎麼在本地建構代碼。

以 React 為例,React 的 Contributing Guide 裡就 Development Workflow 這一節。裡面有這麼一段話:

The easiest way to try your changes is to run yarn build core,dom --type=UMD and then open fixtures/packaging/babel-standalone/dev.html. This file already uses react.development.js from the build folder so it will pick up your changes.

是以 React 倉庫中的 fixtures/packaging/babel-standalone/dev.html 就是一個友善的 demo 頁。我們可以在這個頁面快速檢視我們在本地對代碼的改動。

你可以嘗試着在項目的入口檔案中加入一句 log,看看是不是可以在控制台/終端看到這句 log。如果可以的話,恭喜你,你現在可以随便把玩這個項目了!

理清目錄結構

在看具體的代碼之前,我們需要理清項目的目錄結構,這樣我們才能更快的知道在哪裡地方找相關功能的代碼。

我們看看 React 的目錄結構。React 是一個 monorepo。也就是一個倉庫裡包含了多個子倉庫。我們在 packages 目錄下可以看到很多單獨的 package:

幹貨|如何去閱讀大型前端項目的源碼?

在 React 16 之後,React 的代碼分為 React Core,Renderer 和 Reconciler 三部分。這是因為 React 的設計讓我們可以把負責映射資料到 UI 的 Reconciler 以及負責渲染 Vritual DOM 到各個終端的 Renderer 和 React Core 分開。React Core 包含了 React 的類定義和一些頂級 API。大部分的渲染和 View 層 diff 的邏輯都在 Reconciler 和 Renderer 中。

Babel 也是一個 monorepo。Babel 的核心代碼是 babel-core 這個 package,Babel 開放了接口,讓我們可以自定義 Visitor,在AST轉換時被調用。是以 Babel 的倉庫中還包括了很多插件,真正實作文法轉換的其實是這些插件,而不是 babel-core 本身。

幹貨|如何去閱讀大型前端項目的源碼?

Vuejs 的代碼比較典型,核心代碼在 src 目錄下,按功能子產品劃分。因為 Vue 也支援多平台渲染,是以把平台相關的代碼都放到了 platform 檔案夾下,core 檔案夾中是 Vue 的核心代碼,compiler 是 Vue 的模闆編譯器,把 HTML 風格的模闆編譯為 render function。

幹貨|如何去閱讀大型前端項目的源碼?

Webpack 和 Babel 一樣,可以說都是基于插件的系統。Webpack 的主要源碼在 lib 目錄下,裡面的 webpack.js 就是入口檔案。

上面說了四個項目的目錄結構,那我們遇到一個新的開源項目,應該怎麼了解它的目錄結構呢?

如果這個項目是一個 monorepo,首先我們要找到核心的那個 package,然後看裡面的代碼。

不是 monorepo 的話,一般來說,如果這個項目是一個 CLI 的工具,那 bin 目錄下放的就是指令行界面相關的入口檔案,lib 或者 src 下面就是工具的核心代碼。如果這個項目是一個前端 View 層架構,那目錄結構就和 Vue 類似。

作為驗證,大家可以看一下打包工具 parcel 和前端 View 層庫 moon 的目錄結構。目錄結構這個東西往往是大同小異,多看幾個項目就熟悉了。

debugger && 全局搜尋大法

運作了本地的 build,了解了目錄結構,接下來我們就可以開始看源碼了!之前說了,我們要以問題驅動,下面我就以 React 調用 setState 前後發生了什麼這個問題作為例子。

我們可以在 setState 的地方打一個斷點。首先我們要找到 setState 在什麼地方。這個時候之前的準備工作就派上用處了。我們知道 React 的共有 API 在 react 這個 package 下面。我們就在那個 package 裡面全局搜尋。我們發現這個 API 定義在 src/ReactBaseClasses.js 這個檔案裡。

于是我們就在這裡打一個斷點:

ini複制代碼Component.prototype.setState = function(partialState, callback) {
  invariant(
    typeof partialState === 'object' ||
      typeof partialState === 'function' ||
      partialState == null,
    'setState(...): takes an object of state variables to update or a ' +
      'function which returns an object of state variables.',
  );
  debugger;
  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};
           

然後運作本地 React build 的 demo 頁面,讓元件觸發 setState,我們就可以在 Devtool 裡看到斷點了。

我們走進 this.updater.enqueueSetState 這個調用,就來到了 ReactFiberClassComponent 這個函數中的 enqueueSetState,這裡調用了 enqueueUpdate 和 scheduleWork 兩個函數,如果要深入 setState 之後的流程,我們隻需要再點選

走進這兩個函數裡看具體的代碼就可以了。

如果想看 setState 之前發生了什麼,我們隻需要看 Devtool 右邊的調用棧:

幹貨|如何去閱讀大型前端項目的源碼?

點選每一個 frame 就可以跳到對應的函數中,并且恢複當時的上下文。

結合一步一步的代碼調試,我們可以看到架構的函數調用棧。對于每個重要的函數,我們可以在倉庫裡搜尋到源碼,進一步研究。

Node 工具的調試方法也是相似的,我們可以在運作 node 指令時加上 --inspect 參數。具體可以看 Debugging Node.js with Chrome DevTools 這篇部落格。

其實大家都知道單步調試這種辦法,但在哪裡打斷點才是最關鍵的。我們在熟悉架構的原理之後,就可以在架構的關鍵鍊路上打斷點,比如前端 View 層架構的聲明周期鈎子和 render 方法,Node 工具的插件函數,這些代碼都是架構運作的必經之地,是不錯的切入點。

如果是為了了解一個特定的問題,大家可以直接在自己覺得有問題的地方打斷點。然後把源碼運作起來,想辦法讓代碼運作到那個地方。我們在斷點可以看到局部變量等等資訊,有助于定位問題。

來自開發團隊的資源

其實開源項目的開發團隊也都緻力于讓更多的人參與到項目中來,降低項目的門檻。是以我們線上上其實可以找到很多來自開發團隊的資源。這些資源可以幫助我們去了解項目的原理。

關注核心開發者

每個項目都有一些核心開發者,比如 React 的 Dan Abramov, Andrew Clark 和 Sebastian Markbåge。Webpack 的 Tobias Koppers 和 Sean Larkin。Vue 的 Evan You。我們可以在 Twitter 上關注他們,了解項目的動态。

關注官方部落格和演講視訊

如果我們關注了上面的核心開發者,就會發現他們時常會釋出一些和源碼/項目原理有關的部落格或者視訊。

React 的官方部落格最近就有很多和項目開發有關的部落格。

  • Behind the Scenes: Improving the Repository Infrastructure 這篇介紹的是 React 項目倉庫的基礎設施。
  • Sneak Peek: Beyond React 16

Andrew Clark 一開始就寫了一篇介紹 fiber 架構的文檔。 Dan Abramov 最近在 JSConf 上對 React 未來的一些新特性的介紹 - Beyond React 16。React 部落格中的 Sneak Peek: Beyond React 16 也是對這次 Talk 的介紹。

Evan You 介紹前端架構資料變化偵測原理的 Talk。Vue 文檔中也有 Reactivity in Depth 這樣的介紹原理的章節。

Sean Larkin 的 Everything is a plugin! Mastering webpack from the inside out 介紹了 Webpack 的核心元件 Tapable。

James Kyle 的 How to Build a Compiler 可以讓我們了解 Babel 轉譯代碼的基本流程。

幹貨|如何去閱讀大型前端項目的源碼?

堅持

最後一點也是最核心的一點就是堅持。隻有你長期堅持讀源碼,不停地思考,總結,不斷提升自身技術的廣度和深度,找到适合自己的閱讀方式,閱讀源碼才會是越來越容易的一件事。

繼續閱讀