從一個(gè)開(kāi)源項(xiàng)目到龐大的開(kāi)源矩陣,他是怎么做到的?
大家好,我卡頌。
很多開(kāi)源作者都經(jīng)歷過(guò)如下過(guò)程:
有個(gè)好的開(kāi)源點(diǎn)子
擼起袖子加油干
開(kāi)源項(xiàng)目獲得社區(qū)認(rèn)可,star數(shù)量就是自己的動(dòng)力
隨著維護(hù)時(shí)間變長(zhǎng),遇到挫折(時(shí)間上的消耗、伸手黨的不理解...)
心灰意冷,逐漸停止維護(hù)
今天要介紹的主人公「Tanner Linsley」是React Table與React Query的作者。
Tanner Linsley
不同于其他開(kāi)源作者在激情散去后項(xiàng)目逐漸荒廢,「Tanner Linsley」不僅持續(xù)迭代項(xiàng)目,而且隨著維護(hù)的項(xiàng)目越來(lái)越多,甚至形成了項(xiàng)目矩陣。
上面提到的React Table、React Query,再加上其他四個(gè)項(xiàng)目已經(jīng)合并到TanStack項(xiàng)目下,形成了統(tǒng)一的品牌(TanStack):
他是如何做到的?本文來(lái)聊聊「Tanner Linsley」的開(kāi)源之路。
開(kāi)源的收益
談到「開(kāi)源」,大家會(huì)想到很多標(biāo)簽 —— 「免費(fèi)」、「用愛(ài)發(fā)電」、「貢獻(xiàn)」......
但事實(shí)上,任何工作如果沒(méi)有穩(wěn)定的物質(zhì)收益(對(duì),說(shuō)的就是錢(qián)),都是很難持續(xù)的。
傳統(tǒng)意義上,開(kāi)源作者主要依靠「贊助」(比如Github Sponsor[1])。
相比開(kāi)源的工作量,「贊助」通常是杯水車(chē)薪。所以開(kāi)源作者很難擴(kuò)大自己維護(hù)項(xiàng)目的規(guī)模。
「Tanner」在Github Sponsor[2]已經(jīng)擁有180個(gè)贊助者,算很不錯(cuò)的了。
Tanner的贊助者
但從「擴(kuò)大維護(hù)項(xiàng)目的規(guī)?!菇嵌瓤矗€遠(yuǎn)遠(yuǎn)不夠。
那么是什么使得「Tanner」有穩(wěn)定的收益,從而維護(hù)更多項(xiàng)目呢?
答案是:課程。
TanStack矩陣中的TanStack Query(即React Query)的官方課程[3]已經(jīng)售出8w份了,按當(dāng)前的折扣價(jià)156刀算,這部分收入有稅前1200w刀了。
雖然實(shí)際收入肯定達(dá)不到這個(gè)數(shù),但數(shù)百萬(wàn)刀的收益還是有的。
所以,只要持續(xù)產(chǎn)出優(yōu)秀的開(kāi)源項(xiàng)目,就能獲得穩(wěn)定的課程收益,形成正反饋。
那么,一個(gè)優(yōu)秀的開(kāi)源項(xiàng)目是如何誕生的呢?接下來(lái)我們聊聊React Table的發(fā)展史。
React Table發(fā)展史
在2015年時(shí),「Tanner」是一家創(chuàng)業(yè)公司nozzle的聯(lián)合創(chuàng)始人。
nozzle的主營(yíng)業(yè)務(wù)是:反向爬取Google搜索結(jié)果頁(yè)的數(shù)據(jù),將這些數(shù)據(jù)整合分析后,提供給有SEO需要的廣告主。
這就需要做很多數(shù)據(jù)可視化相關(guān)工作。
當(dāng)時(shí)nozzle的技術(shù)棧是Angular,使用ag-grid實(shí)現(xiàn)表格。
為了項(xiàng)目的后續(xù)發(fā)展,「Tanner」決定將項(xiàng)目整體遷移到React技術(shù)棧。
但當(dāng)時(shí)React技術(shù)棧沒(méi)有優(yōu)秀的表格組件,于是他決定自己實(shí)現(xiàn)一個(gè)。
自用與開(kāi)源的沖突
React Table的最初版完全是為了滿足自用,開(kāi)源只是順手的事兒。
作為一個(gè)開(kāi)源組件,React Table最初的使用方式如下:
<ReactTable
data={data}
columns={columns}
/>
與「自用組件」不同,「開(kāi)源組件」需要滿足盡可能多人的需求。
于是,隨著React Table的star越來(lái)越多,issues也接踵而至。
比如:
能夠?qū)崿F(xiàn)分頁(yè)功能么?
我能給Header組件傳自定義props么?
我能用CSS-In-JS么?
這些定制化需求讓「Tanner」疲于奔命,也導(dǎo)致React Table越來(lái)越臃腫。
最終,React Table有了137個(gè)props配置項(xiàng)來(lái)應(yīng)對(duì)這些定制化需求:
接下來(lái)該如何維護(hù),難道任由React Table的配置項(xiàng)不斷膨脹么?
還好,「Tanner」找到了解決方案,那就是render props。改版后的寫(xiě)法如下:
ReactTable組件只負(fù)責(zé)表格的核心邏輯,內(nèi)部的邏輯交給render props實(shí)現(xiàn)。
想要自定義表頭?自己去實(shí)現(xiàn)。
想要分頁(yè)?自己去實(shí)現(xiàn)。
當(dāng)render props版本的React Table就快實(shí)現(xiàn)時(shí),React核心團(tuán)隊(duì)發(fā)布了Hooks。
于是,React Table重新開(kāi)發(fā)了基于Hooks的版本:
乍看之下,相比于render props的版本,Hooks的版本只是將ReactTable組件變?yōu)閡seTable方法。
但實(shí)際上,這是個(gè)巨大的飛躍。
因?yàn)?,格局一下打開(kāi)了。
格局打開(kāi)
render props可以認(rèn)為是React的一個(gè)特性,他是與React相關(guān)的。
而Hooks本身僅僅是帶有特殊功能的函數(shù),這意味著他可以脫離React單獨(dú)存在。
得益于React Hooks的思想被社區(qū)廣泛接受,越來(lái)越多框架都實(shí)現(xiàn)了自己的Hooks(比如Vue3中的Composition API)。
所以,新版React Table被設(shè)計(jì)為「框架不可知」(Framework Agnostic)。
簡(jiǎn)單來(lái)說(shuō),由@tanstack/table-core再加不同框架的adapter就能實(shí)現(xiàn)針對(duì)不同框架的table組件:
比如,針對(duì)Solid.js,只需要適配他的「細(xì)粒度更新」與context,就能實(shí)現(xiàn)Solid Table:
這種「框架不可知」的開(kāi)源組件擴(kuò)大了組件的受眾范圍,也降低了開(kāi)發(fā)者遷移技術(shù)棧后的上手成本。
后記
開(kāi)源不是打打殺殺,而是人情世故。
按理說(shuō),AG Grid應(yīng)該是Tanstack Table的直接競(jìng)爭(zhēng)對(duì)手。但是,基于「合作共贏」的態(tài)度,兩者形成伙伴關(guān)系,共同致力于:
教育前端開(kāi)發(fā)者這兩個(gè)庫(kù)之間的差異以及如何選擇
當(dāng)一個(gè)庫(kù)不符合需求時(shí),推薦對(duì)方。以求兩者共同覆蓋盡可能多的應(yīng)用場(chǎng)景
AG Grid團(tuán)隊(duì)甚至是Tanstack的大贊助商:
這種「合作共贏,一起把蛋糕做大」(或者說(shuō)「寡頭壟斷」)的開(kāi)源模式,值得廣大開(kāi)源作者借鑒。
你有沒(méi)有用過(guò)React Table或React Query呢?對(duì)于他們發(fā)展至今取得的成績(jī)與收益,你怎么看?
參考資料
[1]
Github Sponsor:
https://github.com/sponsors
[2]
Github Sponsor:
https://github.com/sponsors/tannerlinsley
[3]
官方課程:
https://ui.dev/react-query?from=tanstack#pricing-plans
作者:卡頌
歡迎關(guān)注微信公眾號(hào) :魔術(shù)師卡頌