Luy 1.0 :一個React-like輪子的誕生

小雅發表於2017-10-17

前言

在過去的一個多月中,為了能夠更深入的學習,使用React,瞭解React內部演算法,資料結構,我自己,從零開始寫了一個玩具框架。

截止今日,終於可以釋出第一個版本,因為就在昨天,我跑通了之前的一個小專案。

真的從零開始嗎?

其實並不是,我並沒有重新把jsx解析器進行造輪子,我用上了官方的解析器去幫助我解析jsx。

在正式開始寫Luy的時候,還是比較盲目和恐懼的,原因如下

  • 雖然都知道React是基於虛擬DOM來渲染的,但是虛擬DOM到底是什麼?怎麼運作的
    React的setState是非同步的,這個我們都知道。但是他的非同步和setTimeOut的非同步是一樣的嗎?內部是不是用setTimeOut實現的?
  • react的事件合成系統。在react官方中,幾萬行程式碼,有差不多40%左右是用於模擬事件的。這部分內容是如何實現的?為什麼這麼做呢?
  • React列表中的key為什麼那麼重要?虛擬DOM的優化策略又是什麼?

帶著這些疑問,我要麼是去讀原始碼,要麼去找文章,但是真正弄懂這些知識,可能還得動手自己實踐一次我才會感到安心。

製造這個玩具框架碰到了很多問題嗎?

雖然說現在React-like的框架一大堆,大家都想做出自己的mini 化方案,但是製造一個React-like框架還是超級困難的,可想而知,當初FB工程師們在沒有React的情況下,是如何造出React的,天才。

原始碼解析不多,而且不完備:很多號稱解析React原始碼的文章其實只是非常淺層次的讀一讀,基本上的套路就是,看到哪裡的程式碼,網上一帖就成了一篇文章了,很多知識點還是得親自去打斷電除錯React官方版本才能知道。

好的文章往往只專研了一兩個點,知識點需要慢慢拼湊:網上不乏好文章的,但是好的文章不可能面面俱到。比如有些人研究setState,有些人研究生命週期函式,有些人還研究了ref,甚至有些人研究了Vdom。這些知識點很散亂,非常難以拼湊在一起,基本要花一兩天才能搞懂一個知識點。

  • 虛擬dom演算法:我說實話,虛擬DOM的演算法其實並不難,也就是樹的遞迴遍歷,在遍歷的同時建立和比對。但是奇妙的就是,市面上有一堆虛擬DOM產品,雖然大致相同,但是在處理某些地方的時候不一樣,後文會講。
  • 列表的key:虛擬DOM演算法最難的地方。對應的實際場景就是如下:
<ReactComponent>
  <div key=`1`></div>
  <div key=`2`></div>
  <div key=`3`></div>
  <div key=`4`></div>
  <div key=`5`></div>
  <div key=`6`></div>
  ....
</ReactComponent>

這一個部分難就難在「更新」上,這也是每一款虛擬DOM最不一樣的地方。

為什麼inferno.js這麼快?這個回答裡,其實給出了答案

Luy使用的演算法是:vue2原始碼學習開胃菜,速度上來說非常不錯。

當然我不是吹噓自己的框架有多牛逼,只是實現了這個演算法還是非常開心的。

這部分內容給想學習React原始碼的朋友們

首先,閱讀React程式碼是最直接的方案,但是因為react原始碼實在太多了,我們必須另尋出路。有兩個辦法

  • 閱讀react程式碼最初版本(非常的老了…
  • 閱讀市面上比較成熟的react-mini框架的程式碼

我選擇了第二種方式,可能會有人說哎呀,你水平不夠。我承認,我水平確實不行,讀react原始碼頭有點痛。

我的方法就是先把東西做出來,然後有了基本思路,再看React原始碼你就知道它在幹什麼了。一定要注意的是:框架裡任何一行程式碼都是為了解決某一個或者多個問題而存在的,當你腦海中不能將這些問題和程式碼聯絡在一起的時候,你他嗎根本就是在讀天書。所以,選擇一個程式碼較少的先讀著,理解react的套路

當然,還有很多知識點是通過google得到的,一切來之不易。在讀原始碼的過程中,痛苦但是快樂。

這個框架會有未來嗎?

這個專案其實最初的想法只是學習react的內部原理,但是一路走來我的想法也改變了,會盡自己最大的所能,維護下去,並且跟進react官方的變化(說實話createPortal Luy也是支援的!)

畢竟,學習其實就是模仿,創造永遠在模仿的前提下。最近公司準備上一個新的小專案,也是我第一個全權負責的專案,所以我決定上一把我的Luy進行試點(好就好在,Luy更換react其實是無痛的,實在有什麼問題,直接換react上,哈哈哈

最後

程式碼在這裡,框架地址:Luy,總共加起來目前只有1100+行,不多,可以作為「react套路學習版本」

相關文章