React 纪录片心得 1 — 重新思考最佳实践
2023年2月11日
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 的作者写了一篇{% outerLink href="https://adamwathan.me/css-utility-classes -and-separation-of-concerns" text="《CSS Utility Classes and "Separation of Concerns》" /%}回应。从这些例子都可以看到,当推出一个全新的概念,即使后来被证明是更好的选择,在最开始不见得会受到大家的接受与认可。
正当 Facebook 内部都对 React 的开源失去信心时,有一些 JavaScript 社群中的人,也显露出对 React 的兴趣,这带为 React 的开源带来了一些转机。现在 React 社群中广为人知到 Sophie Alpert、Dan Abramov、Andrew Clark 等人也是在那时候陆续进到 React 的世界中。
如果你有兴趣继续读 React 纪录片的下半段心得,可以看《React纪录片心得II — 社群驱动创新》。