目前流行的後端技術以及框架(Lyft如何將100)
2023-04-15 21:27:32 3
介紹在 2019 年,Lyft 的前端架構需要一次梳理。我們的公司快速增長,新的團隊每天都在開發新軟體系統。那時,我們從一個服務生成模板來生成新的前端服務——用一個我們定製的零配置的前端構建平臺。擁有這樣一種簡單的服務創建方法導致了新服務的爆炸性增長,這些服務使用基於 React 的前端框架構建的各種各樣的代碼。
與此同時,我們在嘗試維護自己的前端平臺(一組內部的 Webpack 配置、ESLint 庫和框架代碼)時遇到了一些不利因素,我們發現自己陷入了對隱藏的構建錯誤進行故障排除的困境,並且普遍發現我們的生產效率被此類支持請求所削弱。由於代碼庫開始分化(就像它們在微服務架構中一樣),我們的開發人員發現升級到我們的前端平臺的新版本的任務非常耗時且令人沮喪。
有 100 多個前端服務和幾乎同樣多的前端工程師,為了 Lyft 的增長,很明顯我們需要做一些事情來確保我們的平臺是可維護的。
我們存在哪些問題?圖片來源:ray rui on Unsplash
我們坐下來列舉了我們面臨的一些核心問題:
分化的基礎設施:新的平臺版本並沒有被統一應用。隨著時間的推移,我們的前端基礎設施開始分化,導致可維護性和代碼複雜度問題。使整個服務群保持最新是非常難的:升級每項服務的責任落在我們的產品工程團隊身上,他們通常很忙且超負荷運轉。這導致服務在安全性和性能更新方面落後。基礎設施的激增(和分化):每個服務根據自己的需求和團隊偏好,以自己特殊的方式實現前端基礎設施(如 Redux,或服務端渲染),導致通用應用程式模式的各種各樣的實現。性能瓶頸:隨著動態導入和其它打包大小優化等技術的推出,尚未升級到我們最新平臺的前端服務,沒有我們新的平臺更新所帶來的性能提升,會在性能方面落後。通用任務很難大規模應用:通常簡單的任何很難大規模應用。例如,如果我們想要將styled-components引入到我們的包中,我們需要手動進入每個服務,根據每個服務的實現方法以其獨特的方法來添加它。缺乏標準化:由於我們各種各樣的代碼庫,共享代碼是非常困難的。我們的工程師在實現模式和模塊時必須重新發明輪子,而不是利用共享的代碼和庫。邁向 Next.js圖片來源:https://github.com/vercel/next.js
我們決定轉向開源社區來尋找一個內生的框架來解決這些令我們頭疼的問題。在評估了不同的平臺後,我們決定使用Next.js!我們喜歡:
其內生的固執己見的理念,將有助於我們統一我們平臺的不同架構。其可執行包裝器,允許我們將所有中心應用程式關注點轉移到模塊接口後面,消除了我們維護自己的構建系統架構的需要。其強大的開源生態系統、友好的社區和可靠的文檔,向我們展示了平臺的未來發展和軌跡。我們本可以直接拿來 Next.js,讓每個人都按原樣使用它,但我們還需要解決幾個問題。
添加一點兒 Lyft 秘料…圖片來源:CHUTTERSNAP on Unsplash
開箱即用的 Next.js 存在兩個問題沒有解決。
首先,我們需要自動化未來平臺遷移。我們需要能夠編寫易於運行且穩固的服務升級,並能夠大規模應用這些功能。為了解決這個問題,我們用jscodeshift設計了一個遷移服務,允許我們發布和運行遷移,在運行升級時自動更新服務代碼。
這意味著,我們平臺中任何未來的突破性變化都將伴隨著自動化的代碼模塊,從而升級宿主應用程式中的代碼。這也意味著,我們可以打開拉取請求來升級整個服務群,而無需產品工程的幹預。
我們需要一種代碼共享的方法。我們希望構建一個可擴展的應用程式體系結構,允許開發人員編寫插件,以儘可能少的配置或粘合代碼,來引入不同的狀態管理器和包。我們圍繞Webpack Tapable設計了一個插件服務,允許我們的任何開發人員將共享的 Lyft 包注入到服務中間件和客戶端 React 應用程式來實現我們生態系統中的不同任務——從 GraphQL 客戶端、Mirage 模擬支持、UI 組件庫到圍繞規範和日誌的共享庫。
開發人員溝通是關鍵一個人不能僅僅靠自己去升級 100 個服務——我們需要驗證和了解我們產品工程團隊的痛點,然後再致力於我們的設計。我們採訪了公司各個部門的工程師,來了解他們在當前平臺上的挑戰和痛點,並收集有關我們的新設計能否解決這些問題的反饋。在我們的內部前端公會全體人員會議上,我們不斷向團隊更新新技術棧的進度。整個過程從頭到尾都是透明的且以開發人員為中心的。
我們將我們的新平臺命名為 @lyft/service,並確定了一小部分開發人員將參與平臺裡程碑發布的 alpha 測試。隨著我們的平臺不斷成熟,我們將受眾擴大到更大的團隊,他們會聚在一起參加為期半天的遷移研討會。做這些會議真的幫助我們建立了一個社區,團隊協作來學習 Next.js 架構,相互幫助修復問題,並了解更多關於我們為什麼做出設計決策的上下文。
Beta 測試以及一些與 React Router 相關的問題我們遇到了一些障礙,這些障礙是在我們開始在 beta 階段遷移服務之後才出現的。例如,我們假設可以將所有應用程式從React Router遷移到Next.js默認的基於文件系統的路由。然而,由於 React Router 在我們的服務中實現的非常具體的方式,我們發現幾乎不可能輕鬆地對這些路由進行模塊編碼。我們沒有從 React-Router 遷移,而是構建了一個功能來允許我們的工程師保留他們現有的 React Router 路由並每次一個路由地分次遷移到 Next.js 路由。
遷移工作如何進行?到 @lyft/service 的遷移非常容易運行。服務所有者只需要調用一個命令:
$ npx lyftsrv upgrade
我們的代碼模塊開始工作並安全地升級代碼。一旦遷移完成,大部分繁重的工作已經完成!
當然,每個服務所有者也必須解決一些零散的問題,比如:
修復單元測試與新的 Next.js 路由集成(或者使用我們的 React Router 實現)升級可能需要手工幹預的包(例如 mobx 或 Redux 的使用)平均來說,從運行遷移腳本到結束零散的問題需要幾天的時間。
結果如今,@lyft/service 運行著我們近 40%的前端服務,而且我們正在加速採用它。
我們看到了這個新平臺令人難以置信的反饋,包括以下優勢:
將開發反饋循環(從代碼更改到瀏覽器更新的時間)減少了 350ms。將打包大小減少了 845kb(在我們的樣本應用程式中)。從每個服務中刪除了 10000 行基礎設施代碼。遷移到這個新平臺將在未來繼續得到回報,因為:
新的升級與 NPM 模塊升級 @lyft/service 並運行遷移 CLI 命令一樣簡單。因為基礎設施代碼完全封裝在一個包(和一套插件)後面,所以遷移所涉及的面比過去少得多。遷移可以通過在整個服務群中自動打開的拉取請求自動完成,所需的產品團隊幹預要少得多,而且所有服務都可以接收到 Next.js 社區所提供的最新最全的更新。有關遷移的更多詳細信息,請觀看Josh在Next.js 2020大會上關於我們的遷移過程的演講!
作者介紹Andrew Hao lyft 和 carbonfive almni 工程師,Wejoinin 聯合創始人,喜歡跑步,酷愛咖啡。
Josh Callender lyft 的 Web 工程師,酷愛電影,美食家,技術迷。
關注我並轉發此篇文章,即可獲得學習資料~若想了解更多,也可移步InfoQ官網,獲取InfoQ最新資訊~
,