React 紀錄片心得 1 — 重新思考最佳實踐

2023年2月11日

💎 加入 E+ 成長計畫 與超過 300+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

Honeypot 在昨天推出了醞釀已久的 React 紀錄片,看到 React 官方的 Twitter 帳號分享,好奇之下點開來看。很意外地得知,原來 React 的發展之路是相當崎嶇的。因為我自己是在 2019 年才接觸前端開發並開始寫 React,在那時 React 已經超越 Backbone、Angular 等框架,成為最熱門的框架,所以我其實並不知曉在那之前發生的事。

看完整部紀錄片,更加了解 React 這個 UI 套件的哲學,覺得收穫很多。所以決定寫這篇紀錄片心得,也推薦同為 React 開發者的人一定不能錯過這部紀錄片。

React 的起始

React 的創始是在 2011 年,當時的時空背景與現在截然不同。JavaScript 不像現在熱門,甚至有「不被當成程式語言」的生存危機。那是因為當時的應用程式主要仍是以桌面應用為主,世界上還沒有那麼多複雜的網頁應用程式。

那時也沒有 FAANG 這個詞彙,因為 Facebook 甚至還沒上市。有別於如今科技巨頭的形象,當時的 Facebook 是以挑戰者之姿在面對 Google 等科技大廠。為了要跟大公司對抗,Facebook 選擇賭注放在網頁應用程式上。

對此,Facebook 內部開發出一個 Bolt.js 的框架,來協助開發者打造複雜且高度互動的 UI。然而隨著越多人加入團隊,Bolt.js 變得很難維護與新增功能。其中的一個困難處在於,維護程式碼的開發者,看這程式碼與看實際的畫面時,要花很多時間才能把兩者對在一起。另一個困難處是是更新畫面,因為你要找到對的 DOM 節點,然後在上面做對的更新操作。

這時 Facebook 的工程師 Jordan Walke 有一個想法,如果在客戶端每次有任何變動時 (例如 API 回傳來的伺服器狀態改變),就重新渲染畫面,這可以讓思考 UI 的開發會更單純一點。而他透過一些函式編程 (functional programming) 的方式來實踐這件事,也因此在最早期 React 正式被定名之前,Facebook 內部是用 FBolt (Functional Bolt)  來稱呼這個新工具。

當 FBolt 被提出時,大家都覺得 Jordan 瘋了,因為這個方式跟過去在開發網頁應用程式的思維完全不同。甚至那時候 Facebook 內部的工程經理覺得 Jordan 把心思投入在 FBolt 上是不正確的分心。因此那時候有另一位叫 Lee Byron 的工程師被派去要說服 Jordan 放棄 FBolt (假如你對 Lee Byron 這名字感到熟悉的話,你的感覺沒有錯,他就是 GraphQL 的創作者)。

Lee 去找 Jordan 時,Jordan 反過來說「我有個很酷的東西想讓你看看」,結果在 demo 完後 Lee 不僅沒有勸退 Jordan,反而被說服。於是他加入幫助 Jordan 釐清想法,讓各種詞彙的定義清楚,最終這個點子得已不只留在 Jordan 的腦中,而是被清楚表達與溝通。

在 Facebook 內部累積動能

在 Lee 協助釐清想法後,開始有其他 Facebook 工程師注意到這個專案。其中一個是 Jing Chen,她認為 React 提出的概念很好,但在這個概念下需要重新思考狀態管理,她也進一步提出了 Flux 的設計模式,這也讓 React 的構想更加的成熟。

在同一個時空背景下,Facebook 收購了 Instagram。在收購時,Instagram 只有 iOS 與 Android,但那時 Facebook 認為 Instagram 也需要網頁版本。在開發 Instagram 的網頁版本時,Facebook 的產品基礎團隊有幾個正在維護的專案,包含上面提到的 Bolt.js、JSHtml,以及慢慢變成熟的 React。

那時在做網頁版 Instagram 的工程師,被 React 的概念深深吸引到。因爲 React 完全捨棄過去的最佳實踐,當他看到這個全新的典範時相當興奮,所以決定用 React 來打造 Instagram 的網頁版本 (備註,在 2023 年的今天,網頁版的 Instagram 每個月有超過 65 億次造訪)。

獲得管理層的支持

除了 Instagram 的收購,當時 Facebook 還有另一件大事發生,就是 Facebook 上市了。因為上市,Facebook 開始有財報的壓力。要讓財報好看,就需要賺錢;而 Facebook 的金雞母是廣告,所以廣告組在當時身負重責大任。那時廣告組花了六個月,把投放廣告的平台從本來的 PHP 用 Bolt 改寫。

不過從技術的角度來看,同時維護 Bolt.js 與 React 並不符合成本效益。但要如何選擇留下哪一個? 最賺錢的業務才剛用 Bolt.js 重寫,這時不繼續維護 Bolt.js 似乎說不過去;但 React 也證明可以讓維護複雜的前端應用程式變得更容易,很有繼續發展的潛力。

在 Bolt 與 React 的角力中,當時 Facebook 的技術長 Mike Schroepfer 介入到其中,他要團隊做對長期來說對的技術決策,即使要停止開發新功能數個月也沒關係。在經過多角度的評估後,Facebook 決定走 React 的路線,並用 React 重寫了廣告相關的平台。

在開源中受挫

React 逐漸在 Facebook 內部穩定後,開始有聲音提出說要讓 React 開源。在這之前 Facebook 開源過幾個專案,但都沒能順利維護。所以當決定要開源 React 後他們花了好幾個月在優化文檔,並做了要好好維護的決心。

只是萬萬沒想到,在 JSConf 發表後,社群掀起了一波唾棄潮。這讓 React 團隊很受挫,因為本來覺得是送給業界的一個禮物,讓業界可以用更簡單與快速的方式開發,但卻是收到這種回應。以為開源社群的大家心態會很開放,殊不知多數人沒辦法接受這種新思維。

在講這段時,紀錄片有截圖了數個當時開砲的推文,我特別注意到 Wes Bos 的推文。為什麼呢? 因為 Wes Bos 算在前端業界小有名氣的人,而他過去開了好幾門 React 相關的線上課程,我還上過;只是沒想到,在 React 剛發表的時候,他竟然也是對 React 開砲的人。

重新思考關注點分離 (separation of concerns)

為什麼當時的業界對 React 有這麼多意見呢? 因為在過去的最佳實踐中,大家認為不應該把 HTML、CSS 與 JavaScript 的檔案放在一起,應該要拆成三份。但有在寫 React 的人都知道,React 的 JSX 語法,以及 CSS-in-JS 的風格,基本上是把三個東西都放在一起。這對當時業界的人來說,是大逆不道,許多人都在社群裡說不知道 Facebook 的團隊在想什麼,怎麼會提出這種東西。

不過 React 團隊在設計 React 時,並沒有違反關注點分離這個概念,而是從不同的角度切入詮釋這個觀點。在 React 中,關注點分離是以元件為單位,所以不是分離了 view 的關注點與 model 的關注點,而是分離了 NewsFeed 的關注點與 Photos 元件的關注點,這是針對前端應用程式關注點分離,截然不同的思考方式。

當時甚至很多人在 Twitter 上發文說,自己收到 Facebook 的招募員寄來的 email,但因為在 JSConf 看到 Facebook 發表的 React,想直接跟招募員說 Facebook 不會是自己想工作的地方。當時 Facebook 的工程總監回憶說,在 JSConf 之後,Facebook 內部自己也認為 React 在 Facebook 以外的地方大概不會有未來。

看到這段讓我想到 TailwindCSS 剛出世時,也是被一堆人抨擊。很多人的論點也是認為 TailwindCSS 的寫法違背了關注點分離 (CSS 跟 JS 應該分離開),當時 TailwindCSS 的作者寫了一篇 《CSS Utility Classes and Separation of Concerns》回應。從這些例子都可以看到,當推出一個全新的概念,即使後來被證明是更好的選擇,在最開始不見得會受到大家的接受與認可。 正當 Facebook 內部都對 React 的開源失去信心時,有一些 JavaScript 社群中的人,也顯露出對 React 的興趣,這帶為 React 的開源帶來了一些轉機。現在 React 社群中廣為人知到 Sophie Alpert、Dan Abramov、Andrew Clark 等人也是在那時候陸續進到 React 的世界中。

如果你有興趣繼續讀 React 紀錄片的下半段心得,可以看《React 紀錄片心得 II — 社群驅動創新》

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們