天天看點

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

作者 | 步天
如何設計阿裡經濟體都在用的搭建服務-天馬

搭建在網際網路技術領域算是一個非常寬泛的概念,從早期大部分人都有接觸過的 wordpress 個人網站搭建,到一些文章類 CMS 系統的圖文編排搭建,再到更複雜的 UI 搭建,特别是 React/Vue 出現後,從架構層面也提供了很多包括視圖結構化(vdom),視圖和資料關聯(資料綁定)等等能力,把原本非常複雜的搭建畫布進行了簡化。

在淘寶,2008年的時候就已經有了第一個搭建系統 TMS(Template Management System),當時的設計也非常大地影響了接下來十幾年的搭建體系設計。

這些設計包括了:

1、前端操作和營運操作分離

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

2、基于模闆的資料挖坑

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

3、頁面渲染的抽象

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

從上面的頁面抽象看,還是有非常多 PC 時代的影子,随着公司的戰略調整,無線化、個性化的發展,搭建系統也随着一起擁抱變化,衍生出了各個面向不同場景、訴求的搭建應用,背後必然也意味着非常多的重複建設。在2019年,随着淘寶、天貓技術部的合并,最終在阿裡前端委員會的支援下,啟動了搭建技術方向,從減少重複建設,提升業務互通的角度,進行搭建應用/服務分層的抽象,天馬也作為經濟體搭建域的統一服務,然後各個 BU、業務都可以基于統一的服務和規範,建設貼合自己業務的搭建系統。

天馬在上個财年完成了十幾個 BU 的接入和搭建支援,整體産出了上萬個子產品,釋出了上百萬張頁面,覆寫了3萬+阿裡營運及幾十萬的商家。

搭建的名詞與概念

搭建是一個多角色複合參與的流程,這是搭建和其他技術方向差異比較大的地方。是以設計搭建的時候,需要先明确重點使用者是誰,需要圍繞什麼角色來設計流程。

為了幫助大家能夠更好地了解後面的内容,首先把一些名詞做一下對齊:

  1. 子產品:非技術同學搭建頁面依賴的最小機關
  2. 頁面搭建:從子產品到頁面的組合過程
  3. 資料投放:資料的變化頻率遠高于頁面,是以單獨提取出資料投放的概念
  4. 終端:目标運作環境

搭建的設計

流程設計

無論在幾年前的 PC 時代,還是現在的無線時代,業務的運作是離不開紛繁複雜的頁面制作的,比如淘寶,從早期不同的行業類目,到現在的不同的導購營銷方式,背後都是需要制作大量的頁面支撐。

整個頁面制作過程,經過抽象。主要是包含幾個步驟:

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

這些步驟應該是可以由營運獨立完成,不需要研發同學介入的。重點講下設定、搭建、投放三個步驟。

  1. 設定頁面:頁面标題、keywords、description 之類的可能會影響到 html 文檔直接變化的設定
  2. 搭建頁面:頁面結構的調整,添加子產品、删除子產品、互動子產品位置等等
  3. 投放資料:針對單個、多個子產品進行資料設定

這些能力背後就是對頁面、子產品、資料的抽象方式,決定了一個搭建的物料應該如何設計。

當然這些流程隻是一個順序,不代表這些操作必須人工進行,即使是自動化生産和搭建頁面,背後系統的流程也是類似的。

搭建核心物料-子產品

子產品是天馬定義的頁面搭建最小機關,頁面由子產品組成,子產品可以和資料進行關聯。

天馬的搭模組化塊有幾個核心的設計原則:

  1. 扁平化
  2. 跨終端
  3. 面向标準資料研發

在前面介紹 TMS 的時候,有介紹 TMS 是如何設計頁面渲染的,除了上下子產品搭建之外,還提供了橫向的子產品搭建能力,當時也叫做栅格子產品。

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

但天馬對這部分進行了簡化,隻支援了從上到下積木式搭建的能力,也就是一維扁平的子產品結構。

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

積木式搭建

對應到頁面就是如下圖:

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

為什麼對這部分進行簡化呢?

  • 對營運友好:從營運同學作為搭建主要使用者的角度來思考,以及無線化場景下,手機螢幕的特征,一維存儲的子產品清單是比較友好的。這個設計也對搭建服務本身帶來了很大的簡化,整個頁面結構就是一維數組,每次操作都可以轉變成一次簡單的數組操作。當然,一維的存儲不代表一維的展示,開發者依然可以在展示的時候,通過一些父子關系,來把一維的存儲結構轉變為樹狀結構。目前我們是判斷把複雜度給開發者,簡單的操作給到非技術同學,還是一個比較合适的方式。
  • 友善建立多端對應關系:因為無線化,公司在無線上的投入比桌面端大很多(主要是消費者側),那麼如果能搭建無線頁面,然後桌面端自動生成,或者反一下,對搭建使用者來說可以省掉很多時間。特别是當下極端一些的場景,使用者搭建一個無線端頁面,需要同時額外生成 pc、weex、小程式的版本。一維存儲的子產品結構可以較好地建立不同終端頁面子產品的對應關系。
  • 友善建立服務端與子產品的關系:因為算法的普及,頁面的個性化不局限于某個商品子產品内部,而是不同人群通路同個頁面,整個頁面的順序都有可能因為個性化而調整。那麼對于後端算法來說,就需要感覺到頁面結構,并和後端的算法模型進行關聯。一維的結構對于這部分還是非常友好的

最早在12年的時候,天貓就已經有了跨終端的概念。如前面的概念定義,這裡不嚴格定義來區分終端、容器等等,先用比較簡單的概念,稱為終端,也就是目标的運作環境。終端包括桌面版 chrome、移動端 safari、tv盒子的 UC 浏覽器、手機淘寶的 webview/weex 容器、支付寶小程式容器甚至到服務端的 ssr 渲染引擎等等。

為什麼不用響應式?響應式隻是跨終端的一種解決方案,響應式解決不了代碼運作在服務端的問題,并且響應式本身也過于注重效率,而不是去面對本質上的差異。

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

桌面端端導航子產品 無線端導航子產品

比如圖裡的導航子產品,無線端是一個 tab ,而在桌面端是一個随屏滾動且懸浮的子產品,這是一個互動差異的案例,而實際上,更多還有内容、業務邏輯上的差異,是以不必拘泥于響應式,該寫兩套邏輯就寫。

當然,跨終端是子產品的能力,如果我的子產品就是隻面向一個端服務,就可以隻寫一個端。

實際的情況會更複雜一些,目前淘系選擇了 Rax 作為統一 DSL,基于上面的搭建設計,加上 Rax 本身一次開發多端運作的能力,就可以實作我隻需要寫一份無線端 web 的代碼,分别轉出 weex、小程式的版本,這樣我的子產品投放到 webview 裡就是 web 模式,投放到小程式裡就是原生小程式,投放到 weex 就可以以 weex 形式渲染。是以一個子產品釋出後,會同時同步到 CDN 和 npm 上,CDN 版本給到純浏覽器和服務端使用,tnpm 部分給到小程式和源碼頁面等其他有頁面級建構能力的場景使用。

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

這個原則比較容易讓人困擾,但實際上,大家在日常研發中,或多或少都在做着相關的事情,比如如何校驗一個表單,如何和後端一起定義一個新的資料接口,以及現在比較流行的 TypeScript 也是在定義資料格式。我們把這個原則分成兩個部分:

  1. 面向資料研發
  2. 資料标準化

資料格式就是一個符合 JSON schema 規範的 schema.json 資料描述,來描述子產品接受哪些入參,也就是子產品面向什麼資料研發。這些入參内部,也做了更多的約定,比如如何讓子產品能夠換膚(和中背景換膚的機制有比較大的差異),如何能夠讓子產品能夠接受一些配置,以及如何給子產品傳遞核心渲染需要的資料。

而标準化的資料格式通過先定義資料模型,然後子產品盡可能去引用已有的資料模型,解決開發者都是寫同一個商品子產品,字段卻不同的問題。否則對于後端來說,得做一套非常複雜的系統來把同樣的商品資料塞到不同的子產品裡,同時還要适配各個子產品不同的字段定義。通常後端同學也不會願意做這個事情。

這些設計背後也就是我們期望開發者研發子產品時盡量脫離業務場景,盡量少的與特定的後端接口互動,把子產品寫的更像一個純做渲染的元件,這樣子產品的流通能力才能得到保障。

下面是一個 schema.json 的案例:

{  
  "type": "object",  
  "properties": {    
    "$attr": {      
      "type": "object",      
      "properties": {        
        "hidden": {          
          "type": "boolean"        
        }      
      }    
    },   
    "$theme": {      
      "type": "object",      
      "properties": {        
        "themeColor": {          
          "type": "string"        
        }      
      }    
     },
    "items": {      
      "type": "array",      
      "items": {        
        "type": "object",        
        "properties": {
          “itemId”: {            
            "type": "string"         
          }        
        }      
      }    
    }  
  }
}           

而那些和業務場景相關的邏輯,就放到頁面級處理,不同的頁面可以共享一套頁面初始化邏輯。

繼續展開講面向标準資料研發,因為搭建本身的特殊性,以及子產品對應的資料不會隻是簡單的進行表單投放,特别是在千人千面、個性化普及的今天,大部分子產品背後,不僅僅是靜态資料,而是一些動态資料服務,這些接口可能會來自于公司大大小小各種不同的系統。對于子產品開發者而言,我定義的資料描述應該面向哪個接口?同樣都是商品接口,A應用和B應用接口傳回的字段,一個是下劃線風格,一個是駝峰怎麼辦。

資料标準化解決的就是這個問題,我們應該面向一個标準的資料進行研發。這個标準資料就是基于目前最底層的這些系統,商品庫、使用者庫等等,統一命名規範後的結果。大家都遵守這個規範來給子產品傳遞資料就可以了。

但實際情況比這個還要複雜,比如有一個子產品,有一行文字描述,部分場景下顯示的是商品标題,部分場景下顯示的是商家寫的宣傳文案,UI 本身是有二義性的。這個時候,我們在資料描述裡就會定義一個叫 title 的字段,具體這個 title 對應實際是 itemTitle 還是 itemDescription,就要看實際的場景。

最後也就是說一個面向搭建域的資料接口,給到前端渲染前,實際可能會經過兩次标準化,一次領域模型的标準化,確定字段是沒有二義性的,然後再是一次VO的标準化,再基于視圖的需求,映射到可能有二義性的子產品展示上。

通常我們會要求後端同學來做好領域模型的标準化,然後前端在 FaaS 或者維護一個類似網關的應用進行視圖模型的标準化。當然也可以前端直接從資料源直接映射到 UI 模型,隻是抽象的層次不同。

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

如何編寫一個子產品

前面有提到,我們還是比較推薦子產品隻是做渲染,盡量少的和特定的場景綁定。那麼簡化一下子產品開發,就是:

  1. 定義我需要什麼格式的資料
  2. 準備好一份 mock 資料
  • 寫一段邏輯,輸入 mock 資料,傳回渲染結果

聽起來很像是一個傳統函數的定義了。

以下是一個 rax 子產品的範例:

import { createElement } from 'rax';
import View from 'rax-view';
import Text from 'rax-text';

export default function Mod(props) {
  let defaultTheme = {
    themeColor: '#fff'  
  };
  let defaultAttr = {    
    hidden:false  
  };
  let {
    items = [],
    $theme: {themeColor} = defaultTheme,
    $attr: {hidden} = defaultAttr,  
} = props.data;
  
return (    
  <View className="mod" style={{
      backgroundColor: themeColor    
  }}>      
    {
        hidden !== 'true' ? <Text>歡迎使用天馬子產品</Text> : null      
    }
     <View className="keys">        
        {
          items.map(element => {
            return (<Text>{element.key}</Text>);
          })        
        }      
       </View>
    </View>
 );
}           

當然,一定會有部分子產品,更複雜,比如有點贊、關注等不隻是一次渲染能解決的事情,這部分一方面是可以元件化的,寫子產品的開發者并不需要關心到這部分邏輯,還是隻需要傳遞一些使用者資訊給到元件就行。另一角度考慮,如果一個點贊接口就有N份實作,對于後端服務設計來說是不是也有問題,是不是推進統一會更好?

子產品研發鍊路的設計

子產品的研發鍊路其實和正常開發一個 npm 包差别不大,基于很多約定,我們提供了一些便捷的腳手架,以及有支援插件化的建構器,可以提供給各種不同但有限的 DSL 子產品進行建構操作。

同時由于開發者有 ISV、外包、内部員工,可視化研發還是非常重要的環節,盡量把哪些和開發一個 npm 子產品有差異的點,都通過可視化研發的方式抹平。我們也提供了包括本地子產品管理、調試、預覽、schema 編輯器等能力,以及代碼掃描、資源存儲等釋出流程的保障。

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

如何研發子產品

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

服務端

因為服務端也是子產品的目标運作環境,目前在服務端運作子產品的方式主要有比較老派的純模闆渲染方式(需要開發者單獨寫一個模闆檔案用于生成 html),以及現在逐漸普及的 SSR 方案。前者足夠簡單且有确定性,後者面向未來但是需要有足夠多穩定性的保障。

用戶端

前面也有提到的,為了讓子產品研發足夠簡單且保證流通性,頁面級需要承擔更多包括資料請求、頁面容器初始化等操作。

資料請求邏輯是頁面邏輯中非常核心的部分,現在會有一些資料驅動 UI 展示的概念,特别是接口合并、分頁分屏、容災打底這些非常重要的功能。分頁分屏決定了首屏需要展示哪些内容,請求哪些資料,然後接口合并負責減少請求數,加速首屏展示,然後容災打底確定最後一定是可以有内容展示給使用者,即使有各種網絡、服務的問題。

而頁面容器渲染,主要還是包括滾動容器的初始化,多元子產品清單的渲染。比如把一維的子產品清單渲染成多tab的父子關系,以及最後需要單獨初始化一個個子產品。

搭建的核心設計-依賴去重

上面的大部分内容和中背景搭建還是比較類似,隻是各自有一些約定。接下來就是天馬的設計中比較有差異的地方了。中背景搭建通常都隻需要在 npm 包元件的基礎上,加上一個 schema 描述,就可以用于在搭建系統中生成對應的表單配置了,npm 元件會在釋出的時候建構到頁面 bundle 中。而是消費者端的不行,目前每個子產品需要單獨進行建構,為什麼這麼做?

背景

  1. 某次活動,大概用到了100+的子產品,搭建出了1000+的頁面。然後有個功能需要在短時間内對特定幾個子產品進行版本更新操作。如果每個頁面都需要建構才能生效,短時間内進行大量建構的可操作性是比較低的,特别是複雜的 webpack 建構耗時還是非常長的。
  2. 在個性化、千人前面普及後,頁面的展示是由資料來驅動的,如果用傳統的建構方案,無法準确做到首屏隻加載首屏子產品,因為首屏本身包含哪個子產品不是由 bundle 決定,而是由資料決定的。

資料驅動展現

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

因為搭建的最小機關是子產品,且業務上有大量動态性的要求,比如某一天10點需要更新1000個頁面的其中5個子產品的版本,把這1000個頁面進行重新建構釋出操作性較低,是以組裝子產品的過程是通過線上渲染服務計算 assets combo uri 實作的,隻要在操作背景點選一下子產品更新,這1000個頁面會自動更新子產品版本而不需要重新走一次建構邏輯。這也意味着每個子產品需要單獨打包,給出一個已經可以在浏覽器上運作的 web 版本。

但是由于每個子產品單獨打包,如果啥都不做,會造成依賴重複加載的問題。那麼就需要把子產品的依賴 dependecies 都 external 掉(也支援主動選擇部分打包),為了確定不重複加載依賴子產品造成頁面大小不可控,引入了 seed 描述依賴的機制。

{
  "modules": {
    "@ali/pmod-ark-butian-test/index": {
      "requires": [
        "@ali/rax-pkg-rax/index",
        "@ali/rax-pkg-rax-view/index",
        "@ali/rax-pkg-rax-text/index"
      ]
    }
  },
  "packages": {
    "@ali/rax-pkg-rax": {
      "path": "//g.alicdn.com/rax-pkg/rax/1.0.15/",    
    },
    "@ali/rax-pkg-rax-view": {
      "path": "//g.alicdn.com/rax-pkg/rax-view/1.0.1/",
    },
    "@ali/rax-pkg-rax-text": {
      "path": "//g.alicdn.com/rax-pkg/rax-text/1.0.2/",
    },
    “@ali/pmod-module-test”: {
      "path": "//g.alicdn.com/pmod/module-test/0.0.9/",
    }
  }
}           

光有一個描述肯定不夠,核心還需要确定一個政策,子產品依賴同個 npm 包的不同版本,應該如何選擇。npm 安裝的方式是相容版本取最大,不相容或者指定版本的時候安裝多份的政策。web 上的政策也是類似的,隻是内部的研發更可控,是以把這個政策做了更多的簡化(以x,y,z版本為例):

  1. x 位大版本可以共存(也可以選擇不共存)
  2. y,z位版本變化都是向前相容的,會自動取相容下的最新,即使指定了版本。

從 web 和使用者側的角度考慮,加載大量同元件的不同版本隻會造成頁面體積的膨脹,帶來帶寬、流量的浪費,以及使用者側較差的體驗。

本質上,就是把原本 webpack 幫開發者做的内部依賴管理,抽象提取出來,在頁面級統一進行管理。

seed 機制與 webpack

seed.json 依賴關系的問題

第一個,私有實作帶來的了解和建構成本

天馬目前的 seed 配置核心問題在于這是一個非常私有的實作,所有元件要進入天馬體系并且有去重能力,就得重新建構以此生成 seed。

這個問題在新業務接入天馬的時候會比較明顯,因為頁面級去重能力是基于 seed 配置來的,而 seed 的原始來源是元件内部的 seed.json,也就是說你要先把元件内的 package.json dependencies 轉成 seed.json,然後這個元件才能被收集依賴。這也是為什麼需要把元件在天馬上注冊一次,注冊的過程也就是生成對應 seed 的過程。目前這個過程是手動引入元件然後送出一份到天馬。後續天馬子產品中心會提供自動注冊的能力。

那為什麼沒有直接根據 package.json 來進行注冊的方式呢,畢竟 seed 也是由 package.json dependencies 生成的。

主要原因有:

  1. package.json 裡聲明的依賴并不一定會用到,還需要讀取真實的 import 引用情況
  2. package.json 裡聲明的依賴并不一定都是公共依賴,内部依賴就直接打包掉了,不然不公共的依賴放到 seed 裡,seed 本身的體系會非常大
  3. 公共元件需要釋出一份到 cdn,并轉成 Web 上可運作的 CMD/UMD/AMD 等等,本身也需要一個建構過程。

第二個,對複雜 loader 的依賴

由于 seed 檔案的存在并且包含比較多的關系描述,需要一個相對複雜的 loader 來解析這個描述,嘗試過基于 SystemJs 進行擴充,但是動态性上還是無法和原本自研的 loader 相提并論。有興趣的同學也可以看下 KISSY 3 的 loader 實作。

webpack Module Federation 可能的問題

1、HTML 的組織

基于 seed json 格式, wormhole 內建了通過 seed.json 生成 HTML 的能力。開發者可以不需要關注 HTML 如何生成,因為 loader 的保障,順序也沒有那麼重要。

在 Module Federation 的使用情況下,HTML 還是依賴頁面級建構,如果需要在類似搭建場景下動态拼裝 HTML,要不就加載所有的 remoteEntry 檔案,要不就是得自己提出一個依賴關系出來給到服務端生成。

當然,也可以直接用 SSR,這樣的話,就需要另外一個配置來打包一個 SSR 版本的代碼,畢竟服務端按需意義沒有那麼大,并且,SSR 大機率也隻能覆寫頁面的部分内容,剩下的還是要面臨如何組織 HTML 的資源引用的問題。

2、備援的代碼

因為 Module Federation 把依賴都通過代碼的方式打包到了 remoteEntry 檔案裡,那麼必然會存在很多重複定義的代碼。比如 webpack _require 下的一堆函數,remoteEntry 加載多了,這個問題會相對嚴重一些。

不過對比目前天馬依賴處理體系來說,feloader 本身因為曆史原因+支援了KMD/CMD/AMD等多種子產品格式,也有點尺寸過大,是以也有類似的問題。

3、CDN combo

通過 seed.json 描述的依賴關系,是可以快速解析到一個 combo 格式上的,通過一個請求把依賴的腳本合并取到。而目前 Module Federation 每個 remoteEntry 都是獨立處理,雖然對比 SystemJs 或者其他 webpack 分包插件,有能力處理深度依賴(依賴的依賴不重複加載),但是缺乏一個合并能力,可能會出現串行加載依賴的情況,不過這個問題擴充下 trunk loader,合并依賴元件 promise 函數的處理,不是很難解決。

搭建的核心設計-渲染服務

上面講的更多還是圍繞搭建的物料,天馬還提供了通用的 Node.js 線上渲染引擎,用于提供統一的渲染服務,隻要通過天馬搭建的産物,都可以被渲染服務消費,并渲染出最後的結果給到使用者通路。

模闆渲染本身沒有特别的點,主要說一些不同的。

多終端的緩存

面向阿裡大流量的場景,我們設計了一套多終端的緩存方案:

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

子產品是支援跨終端的,那頁面也肯定是跨終端的。而這背後是需要統一的終端識别架構來支撐的。目前搭建産物的頁面都是托管在一套緩存+源站架構下的,不同的端會有一份對應的緩存副本,避免每次通路都需要重新渲染。

基于這樣一套架構,我們也可以實作營運隻需要投放一個位址或者二維碼,在不同的端就有不同的展現方式。

高性能保障

在支援跨終端的同時,渲染引擎也承擔着類似 webpack HtmlWebpackPlugin 的職責,搭建系統釋出出來的結果是一個包含頁面結構、依賴關系的描述。渲染引擎通過這個描述渲染出 HTML、weex bundle 等。當然這個過程會有一些耗時,主要是在以下兩個部分:

  1. 拉取子產品的資源檔案,檔案需要從 OSS 遠端拉取
  2. 計算整個頁面最終的依賴關系

因為渲染服務是線上的,算是基于 CDN 緩存架構的實時渲染(每隔一段時間自動更新回源),如果與 webpack 一樣建構速度緩慢的話,還是非常糟糕的事情。是以在這裡也做了很多包括依賴關系計算的緩存、檔案的緩存等等。然後再通過 CDN 緩存的能力,提升整體的通路速度。

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

同時為了提升使用者通路體驗,渲染引擎的部署範圍是大于搭建服務的,特别是在國際化場景下,渲染引擎已經部署到了亞歐美,并且為這些國家專門做了 OSS 檔案同步優化。

未來展望

seed 體系與 webpack 的長期融合方案

天馬獨有的這套 seed 依賴關系機制,因為沒有像 webpack 那樣把依賴關系隐藏起來,還是有一定的學習成本的,并且也容易造成一些問題(當然 webpack 也有他自己的複雜和學習成本 )。

是以那些頁面量不大,且沒有淘系這樣相對比較變态的更新訴求下,因為子產品本身也是一個标準的 npm 包,天馬也支援了離線建構的方式,這個方案就更貼近 react 源碼app的開發,可以做更多的建構時的優化,同時産物也脫離了 seed 體系,渲染過程得到了簡化。

長期來說,随着 webpack 本身的發展,最終還是期望能夠逐漸合并到社群方案上,在頁面建構和動态化能力之間達到一個科學的平衡。

動态化

而對于淘系自己來說,動态化始終是一個重要的能力,我自己的設想是,如果今天我們可以不用打包子產品,直接把源檔案釋出到 CDN,把 CDN 當做目錄,直接在浏覽器上跑一個類似 webpack 的能力,就可以在保留動态性的同時,也不會帶來額外的複雜度(複雜度都在方案本身了,對開發者來說,就不需要了解太多)。

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

為什麼這隻是一個展望呢,要這麼做,還是需要面臨一些問題:

  1. 浏覽器的性能是否足夠做這樣的編譯,特别是目前在 webpack 本身編譯就是一件耗時的事情,把這部分時間扔給使用者側還是有點可怕的。
  2. 遠端檔案系統在網絡上的時間消耗,雖然可以設計很多緩存機制,但是首次依然是個問題,并且繞開浏覽器本身的緩存機制,做一套檔案緩存還是會有很多問題,特别是在無線端 app webview 内,空間是非常有限的。
  3. 包管理的複雜度,目前的 seed 機制已經做了類似的事情,不會帶來太多包管理方式上的變化。

0研發

面向未來考慮,對于開發者來說,寫的代碼能夠更自然且簡單的運作,了解成本和維護成本都會降低很多,無論是完善的開發者配套工具,還是友好的子產品化設計,都是為了提升開發者體驗。

但是人能做的事情始終有限,目前天馬也在和 imgcook 和 iceluna 做更多的合作,,結合可視化、智能化代碼生成代碼,開發者可以更加專注于維護一個機制或者工程,來系統性提升使用者體驗,豐富業務玩法,而不是投入到無止盡的頁面制作上。

天馬作為一個搭建服務,還是和阿裡的業務綁定的比較多,上面講的内容也隻是天馬的一部分,剩下的部分還不适合對外。未來也希望能夠有更多的管道,如開源、上雲的方式,把天馬的服務以及背後的思考分享出來,也歡迎對搭建有興趣或者有想法的同學來做更多交流。

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

關注「Alibaba F2E」

把握阿裡巴巴前端新動向