如何開發和部署前端代碼?淘寶8年案例解讀

在加入淘寶後,經歷了大大小小的開發和部署方式的更迭,同時也有幸在整個的變革潮流中參與過其中的一些能力的建設。今天從一個親歷者的角度,通過自身經歷與向同事考究,從“13年石器時代”、“14年白銀時代”、“15年黃金時代”以及“未來時代”四個階段和大家聊一聊大廠是怎樣開發和部署前端代碼的。

在阿里的淘系前端團隊,開發與部署的模式隨着技術的發展,仍然正在處於不斷變化的過程中。一方面體系內外紛繁複雜的能力模塊不斷地向前發展,另一方面 LSP、DAP 等底層技術基礎也逐漸成熟。在當下我們正在通過集成研發環境 IDE 的方式,將上一個階段孵化沉澱的研發生態進行再一次的整合昇華,將原有的鏈路再次重組,從當下用戶的痛點中找到突破口,發掘當下各個研發場景中的最佳能力組合,搭建通用底層平臺,升級變革現有模式。

作爲從 14 年實習到 15 年正式進入公司的前端開發,在前身爲淘寶前端團隊的 淘系前端團隊 經歷了大大小小的開發和部署方式的更迭,同時也有幸在整個的變革潮流中參與過其中的一些能力的建設。今天從一個親歷者的角度,通過自身經歷與向同事考究,以分階段的方式來進行回憶和描述。

回答將整個故事分成四個階段,首先是 13 年左右以代碼發佈存儲、部署改造成 Gitlab 技術體系爲主旋律的 “石器時代”;14 年左右伴隨着 NodeJS 技術成熟,用前端 JS 語言建設工程化工具的 “白銀時代”;從 15 年開始,在藉助 NodeJS 技術完成工程化工具嘗試之後,更系統化建設線上線下前端工程化體系的 “黃金時代”;以及在當下我們正在通過客戶端、容器、算法等多元化技術打造未來研發模式的"未來時代"。

石器時代

在 13 年前,前端的研發模式其實與後端研發的方式沒有太大的差異,大部分是基於 SVN 進行 SCM 代碼管理。在完成每天的代碼研發工作後,通過命令行或者 小烏龜 等工具將代碼上傳到 SVN 服務器中完成一天的開發流程。在部署階段,通過手動拷貝或者 FTP 上傳的方式,將測試代碼進行上傳到測試服務器上,在完成測試之後,人工檢查下代碼版本及內容,然後進一步上傳到生產環境,完整整個研發部署流程。

在那個時期,代碼管理工具除了 SVN 之外,也出現了基於 GIT 協議實現的代碼管理工具 Gitlab。面對 SHA-1 算法帶來的版本檢測便利性、本地分佈式的代碼版本控制的靈活性等優勢,我們逐步將部門內的 SVN 研發工作流程遷移到了 Gitlab 上。同時這個變化也算是淘系前端研發變革的起源。

在經歷代碼版本管理工具切換帶來的便利同時,我們思考當時較爲操作繁瑣、需要人工保證的部署流程是否也能進一步的在新的體系上得到改善。在新版發佈系統的背景下,我們在新的 Gitlab 系統所提供的各種能力中,發現可以將 webhook 機制進行一定的上層封裝,藉助規則化的操作,來觸發與發佈系統的關連,自動完成發佈上線流程。我們基於 publish/版本信息 這樣固定規則的 Git Tag 來觸發 webhook 事件通知,觸發發佈系統的調用上線流程,從而完成了第一個實際意義的前端研發全自動化發佈流程。

這個階段就像 “石器時代” 般原始,不過在完成了研發基礎設施這塊如釜底抽薪般的改造之後,爲後續的發展提供了堅實基礎。同時隨着前端技術發展的契機,我們也基於這套底層體系進入了新的階段。

白銀時代

在 14 年左右的時候,已經誕生 5 年多的 NodeJS 技術也逐漸變得成熟起來,當時團隊基於 NodeJS,產出了一套名爲 DEF 的研發本地端 CLI 終端工具,工具的核心是一套 Node 模塊的安裝、調用管理機制。工具開發者通過將研發功能模塊封裝成 DEF 體系下的 插件 形式,通過不同 插件 模塊的調用組合,來實現對前端項目的編譯、調試、上線等操作。

在當時 KISSY 框架研發體系下,我們藉助 NodeJS 的能力,通過正則匹配、 UglifyJS 解析 AST 等方式進行腳本編譯處理,通過 JS 技術開始構建起前端領域的工程化工具,逐漸替代掉了以 java 體系中藉助 Ant 平臺實現的工具。

在當時我們除了藉助使用 yeoman 等工具來完成初始化流程,也隨着業務編譯構建邏輯的不斷抽象產出 構建器 這樣的基礎概念。

當時在傳統的項目組織中,構建編譯的配置邏輯與項目的代碼文件是放置到同一個代碼目錄中。從團隊視角下,這塊構建編譯邏輯零散自由,談不上有統一的更新管理邏輯。如果團隊內某一類的研發場景構建編譯工具本身有任何的更新變化,在團隊範圍內工具的更新覆蓋將需要消耗非常大的成本;與此同時,在用戶的角度,在相同類型的不同項目中,也存在着大量重複安裝的構建依賴,每一個項目在構建前也都需要安裝一遍構建依賴,在空間和時間上都有一定佔比的浪費。

通過 構建器 概念將編譯構建依賴進行收斂、抽象,將項目的編譯依賴維護在一個 npm 包中。這樣編譯邏輯就從多對多變成了一對多,在大幅降低構建邏輯的空間佔用的同時,也能較好的複用已經安裝的構建依賴,簡化構建環節,提升構建效率。進一步也爲後續的線上構建體系埋下了伏筆。

在這個階段,NodeJS 技術也逐漸變成了我們除日常頁面開發之外的又一個基本技能。伴隨着 NodeJS 工具的誕生與規模應用,前端開發與部署從 “石器時代” 進入到 “白銀時代”。隨着大家對 NodeJS 體系的基本運用變得愈發成熟,我們在基礎體系的使用之上,進一步開始進行更深入的思考發散和抽象設計,開始建設更成熟的前端工程體系。

黃金時代

在團隊完成基於 NodeJS 技術的工程工具以及 Web 服務框架等基礎設施建設之後,在隨後的幾年時間內,越來越多的更爲成熟的線上線下的工程化體系發展起來。在那個階段設計、建設的服務、工具後續也逐步形成了如今淘系前端研發、部署流程中的基礎設施。

研發套件

隨着本地 DEF 工具的發展,越來越多工具插件雨後春筍般地湧現出來。一方面用戶有着非常多的工具選擇,基本上本地研發過程中的功能都能在插件生態中找到;但是另一方面,在實際用戶視角下,在某一個項目開發的時候,用戶需要對這個項目使用到的插件以及插件用法要有一定的熟悉程度、知道最佳的組合使用方法。隨着項目逐漸變多,對於工具組合的記憶成本變得高起來,同時也需要注意到不同項目之間插件組合的切換。

在百花齊放之後,面對延伸出來的問題,在原有的本地 DEF 工具之上,我們提出了 研發套件 的概念。通過對本地研發過程中進行總結收斂,抽象出 init 初始化、dev 編譯預覽、build 構建、test 測試、publish 發佈 這五個本地工具的功能節點。將原有的插件能力根據項目研發類型進行分類後,總結沉澱出每一類研發類型的標準本地工具 --研發套件。

藉助套件概念的封裝,用戶在不同項目之間研發的時候直接通過 統一的命令 ,就能完成項目研發對應工具服務的啓動使用。同時在新的本地套件體系,也能針對每一位用戶有着更細粒度、靈活的版本指定方式。配備更完善的日誌監控體系,在使用工具的用戶遇到問題時能實時感知、解決,最大程度保證一線同學本地研發工具的使用體驗。

研發部署平臺

在藉助 Gitlab 的 webhook 能力發佈前端資源的流程成熟之後,一方面在發佈流程上研發用戶期望有更優化的發佈體驗,另一方面團隊對於前端研發流程更體系化、結構化的流程治理、數據統計也有了更高的要求。

在這樣的背景下,我們通過打通原有鏈路上發佈能力,將發佈鏈路中各個環節進行更友好的串聯,產出了前端體系下的研發部署平臺。在體驗上,用戶可以藉助一個簡單的命令行命令直接開始發佈任務的啓動,簡化了發佈時 git 發佈 tag 的操作流程。在整個發佈流程中,通過長連接的方式將各個環節的運行信息、日誌進行返回展示,提供了全新操作的一條發佈鏈路。用戶第一次開始對發佈流程有着更全面的掌控,從開始進行代碼的提交檢測到最後資源 cdn 上線都有着完善的信息披露,極大的提高了發佈體驗。

基於內部 NodeJS 實現的研發部署平臺,在完成了基礎鏈路的打通之後,在更體系化的角度上也逐步地開始作爲工程研發上線流程的基礎,對原有的上線發佈鏈路的進行重塑。將原有流程中的環節進行抽象,逐步分散到 構建、檢測、發佈 三個主要步驟。在隨着業務研發類型從 PC 到無線的切換過程中,基於三個基礎步驟,在執行上層也逐步孵化出前端領域下 發佈類型 的概念。例如在當時存在着 Web 應用類型、前端資源類型、Weex 應用 等類型,底層系統針對每個細分的 發佈類型,在整體的發佈流程的細節對接上採取不同的發佈部署方案,本地研發結合套件工具,形成線上、線下鏈路關聯統一的研發組合方式,更精細化地爲每一種研發模式都提供最佳的研發部署體驗。

用戶從此之後就不再需要通過 Gitlab 的 webhook 觸發發佈流程,“一鍵上線” 代表着前端工程體系又進入新的一個階段。

雲構建

在上一個階段中,我們通過將編譯邏輯經過中心化封裝的方式,藉助 npm 的形式,形成了在研發編譯構建環節的規範描述。但是在部署上線環節,構建器並未與線上部署流程進行串聯,而不同的本地系統環境,同樣也會導致構建結果的不穩定。

在當時伴隨着 docker 技術的發展,我們思考通過 docker 快速啓停統一環境的能力來實現一個構建器運行的環境,通過 docker啓動的 container 容器來模擬執行本地的編譯構建流程。同時利用統一的容器環境,結合前文介紹的遷移之後的 Gitlab 提供的 commit等版本標識信息,能在最大程度上保證構建內容的穩定統一。

經過了一段時間的摸索,通過在體系內經歷了例如 建立前端 docker 容器集羣、串聯打通容器與應用的網路通道、建設構建任務調度策略邏輯、藉助 redis 打通 docker 容器運行日誌等技術環節的驗證探索之後,我們基於容器技術搭建起來了在前端持續集成領域的 雲構建 系統。

在通過淘系的 NodeJS 應用框架 midwayjs 完成線上構建能力搭建的同時,在業務側我們也在逐步建立更友好、完善的線上構建業務邏輯。藉助在線上發佈流程時調用 雲構建 服務,在整個構建任務的執行流程中,串聯起來了 構建器、倉庫、用戶 三者的業務關係。在這個關係網下,我們建立了完善的任務執行情況的調度管理,能完整記錄構建器任務執行的具體情況。

在構建器視角下,可以看到構建器針對不同倉庫的執行情況,有着完整的運行日誌與構建時間、構建錯誤記錄,方便用戶針對構建器進行錯誤排查以及性能優化。而針對構建器的迭代更新,構建器開發者可以針對用戶進行灰度範圍劃分設置,在版本更迭時通過完整的灰度流程保證上線的穩定覆蓋。在構建器發佈過程中如有問題,立即取消灰度進行處理。通過這樣的模式,最大化地降低發佈版本的風險。在針對橫向覆蓋較大的場景下,完整的灰度發佈機制起着舉足輕重的作用。

用戶在研發過程中需要將本地構建代碼推送到倉庫的這個環節也從此變成了歷史,在源碼完成開發之後,直接提交源碼到倉庫中,執行發佈任務的同時,雲構建系統會自動構建出穩定、統一的構建產出結果。

門神

在完成在完成項目的編譯、壓縮過程之後,看似已經走到部署環節的前端資源,在面對不斷複雜起來的業務場景下,實際仍然存在着許多隱蔽的問題,而以往通過人工檢查的方式已經逐漸無法保障上線資源的可靠性。在這樣的背景下,也需要一個流程化、規範化的方式進行系統干預、檢測,做好發佈資源的最後一道防線。

與 雲構建 類似,基於 NodeJS 搭建線上資源檢查運行環境,通過將檢查邏輯也進一步抽象化,同樣以 npm 的形式進行承載抽象出 檢查器 的概念。在用戶資源完成所有的前置處理後,再進入到門神系統並行檢查任務的執行,在完成例如 資源地址、敏感詞、代碼註釋 等等檢查之後,通過不同分級的檢查結果,反饋用戶相應的處理方式。作爲上線前資源的最後一道關卡。系統取名 門神 寓意保障每一次的發佈資源的上線基本質量和安全。

通過門神自動化的方式,用戶不再需要在上線前"火眼金睛"檢驗各種無法通過常規編譯工具發現的問題,輕鬆上線。

能力開放

一方面隨着體系內前端工程領域不斷的發展,不斷有更多的研發解決方案隨着業務場景的不斷髮展湧現出來,另一方面隨着體系內 研發部署平臺、雲構建、門神 逐步成爲集團前端研發場景的事實規範和基礎設施。在這個背景下,底層能力得到了進一步抽象開放的契機,上層的業務體系可以根據自身的業務情況,通過藉助成熟的底層工程中臺能力搭建屬於自身業務體系的前端研發流程。

例如從阿里體系視角下,不同的投放客戶端,不同的資源組織形式,藉助通用抽象化的底層工程能力,最終讓每一個業務場景的開發者都能擁有在項目業務場景下的最佳研發體驗。

貝搭建平臺

如何設計阿里經濟體都在用的搭建服務—天馬

除了常規的項目研發,在電商體系下,特別是在營銷場景下存在着需要快速生產頁面的需求。在這樣的業務場景背景下,孵化出來了通過模塊生成頁面的搭建平臺。通過將頁面進行重新劃分,分割成 頁面骨架和 頁面模塊 的方式,通過前端同學開發這些頁面元素,完成開發後進行組合搭配,同時打通業務數據流,實現快速搭建頁面的能力。

前端研發同學在完成本地模塊開發後,將模塊資源進行發佈到線上,在搭建系統中進行頁面組裝和上下文注入預覽後,完成頁面級別發佈。在底層同樣藉助 NodeJS 實現的源站系統來承載 CDN 內容的分發回源,提供億萬用戶的訪問預覽。這套體系經過幾代的發展更迭,已經成爲當下前端研發的最核心場景之一。

大致從 15 年開始的幾年時間裏,伴隨着技術的發展,淘系前端的研發體系從最初的本地工具、研發部署平臺作爲排頭兵,逐步發展成線上線下的體系化專業解決方案。在保證前端角色的研發基礎體驗不斷突破升級的同時,企業化規模化的前端工程建設將日常零散的研發形式不斷推向更體系化的、高效率的、可擴展的 研發模式,同時也爲後續更上層的研發部署模式的突破和升級打下堅實的基礎。

未來時代

在逐步成熟的工程體系之上,在最近的幾年時間內,我們也在思考面對 研發提效 這件事情上,是否還能有更突破的、面向未來的解法。隨着許多內部產品不斷地改造和迭代,也不斷浮現出了星星之火可以燎原的方向和模式。

D2C

imgcook 項目最初起源於可視化搭建,到目前外部看到的研發模式也是經歷了不斷的改進、變化。在整個的研發模式變化中,從外部的視角大致經歷幾個階段 :

  • 第一階段:當時的用戶的使用方式是通過頁面元素的拖拽進行頁面搭建,產出源代碼之後進行發佈上線。
  • 第二階段:通過建立圖像掃描引擎進行像素掃描佈局,同時接入 sketch 等視覺設計工具,自動的將設計稿進行轉換,這個階段前端用戶的研發方式式就開始變化成了將視覺稿進行上傳到平臺處理進行代碼轉換;
  • 第三階段:在當下的第三個階段,平臺正通過深度學習等人工智能技術來提效圖像代碼轉換的能力,與此同時在平臺端完善基礎研發鏈路的打通。內部的研發模式也正逐步切換到了在設計、代碼的工作臺中進行操作,實現一站式研發、上線的操作體驗。

目前 D2C 能力逐步在智能化還原組件、表單、模塊、頁面的研發場景中逐步得到驗證並收穫一定的成果。

IDE

在最近的一年時間,我們也逐步投入到了新的 IDE 方向建設中,期望通過 IDE 的平臺能力來孵化新的更高效的研發模式。

外部趨勢

從外部視角來看,可以看到有兩個趨勢浮出水面。一個是 IDE 領域相關的創業公司逐漸浮現出來,出現了許多相關的創業明星公司,例如有 Eclipse 體系下的 theia ,通過兼容 VSCode 接口實現的 coder,以及研發編輯領域的行業新秀 codesandbox;另一個是雲廠商的加入,AWS 收購 Cloud9、騰訊收購 Coding、Azure 提供 Codespace 服務。

在編輯器、Docker 等技術的不斷髮展成熟之下,各個 IDE 相關服務廠商都希望能借助集成研發環境的能力來找到研發效率、體驗提升的機會,從而抓住用戶的痛點,擴張產品市場。

內部體系

前端研發模式隨着不斷的分化、發展,湧現出越來越多的工具、服務。當下工具、服務的形式也不單單只是前文提到的命令行終端工具,或者說終端工具也逐漸成爲了富交互的工具、服務的啓動入口。同時一種業務研發模式往往也需要串聯到不同體系、不同團隊提供的研發工具、服務。舉一個例子,例如當下支付寶小程序的研發,除了基礎的編譯服務、預覽服務之外,需要用到模擬器、調試器、真機調試等等服務。

支付寶小程序其實是內部很多場景的一個縮影,支付寶小程序當下的解法其實是藉助 Electron 平臺打造了一款本地的 IDE 研發工具。在這樣的背景之下,體系內去年也開始了 IDE 底層體系 的搭建。期望能通過一套 IDE 底層實現線上、線下的基礎 IDE 解決方案。

藉助 IDE 底層插件機制,淘系也孵化出自己的 IDE 集成研發工具,例如前文提到的 D2C 、支付寶小程序、serverless 等場景都在緊鑼密鼓的進行內部拓展和使用改進。我們通過 IDE 及 IDE 的插件體系,一方面藉助 VSCode 的生態完善基本研發體驗,另一方面通過插件在 VSCode 能力範圍之上擴展的插件 UI 能力來串聯起單個項目鏈路上所涉及到的所有的工具、服務。

與以往的流程的不同的是,除了將線上的發佈部署流程進行串聯整合,研發同學在當下所有的在研發過程的操作包括 研發編碼、調試預覽、部署流程 都在統一的研發 IDE 中有機的銜接起來,直接通過研發面板完成所有操作。這是我們爲未來埋下的一顆種子,正在慢慢發芽。

整篇答案其實從一個在體系內的員工角度向大家介紹了關於淘系前端研發部署相關的一些歷程,當下的研發模式我們也在日赴夜繼的探索突破,最後介紹下團隊做的事情。

鏈接

本文轉載自公衆號淘系技術(ID:AlibabaMTT)。

原文鏈接

https://mp.weixin.qq.com/s?__biz=MzAxNDEwNjk5OQ==&mid=2650408069&idx=1&sn=f2e5d7f86478a45ec10ed587eb6d29ff&chksm=8396cc9db4e1458b48e0ce4125621665de32103561c8250b3937ff3e29568d8952a5ede55a92&scene=27#wechat_redirect

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章