前端提效:使用「工程方案」代替「腳手架」

語言: CN / TW / HK

腳手架的演變

在前端研發活動中,腳手架負責專案的初始化工作,是後續研發活動的基礎。一個典型的研發活動流程大概是這樣:執行腳手架建立專案 -> 開發 -> 構建 -> 測試 -> 部署。團隊規模較小或者業務比較簡單的時候,可能也用不上腳手架,比較常見的專案初始化方式是直接從一個已有的專案中拷貝一份出來,然後酌情刪除業務相關程式碼,保留和修改基礎程式碼。如果業務發展比較快,隔段時間就需要新建一個專案,這種方式無疑比較繁瑣,於是有了第二種方式。把上一種方式形成的模板程式碼上傳到倉庫中維護起來,需要新建專案時,將倉庫程式碼 clone 出來,刪除 .git 目錄,重新上傳到新專案的倉庫。而且後續可以持續迭代這個模板倉庫,維護性更好。每次新建專案都需要走一遍如下過程:clone 程式碼 -> 刪除 .git 目錄 -> 關聯並 push 到新倉庫,略顯繁瑣,於是有了第三種方式。將這個過程封裝成 CLI 命令,比如叫做 fe-cli ,每次需要新建專案只需要執行 fe-cli projectName 即可。得益於 Node.js 生態的繁榮,封裝這個 CLI 並不難,只需綜合運用好相關庫即可(如 commander``inquirer``shelljs 等)。更進一步,可以在這個 CLI 裡實現模板選擇功能,這樣的話,就可以支援不同型別的專案建立了。

腳手架的維護成本

用完即拋

一個顯而易見的問題是,如果不是專門做基建的團隊,花費時間和人力成本維護這樣一個腳手架似乎有點得不償失。腳手架的功能做得再豐富,互動性再好,也只是用來建立專案,生成一堆模板程式碼,專案建立好了就放置一邊,等到下次建立再撿起來。

版本升級

還有一個比較麻煩的問題是,如果腳手架做了升級,除非在腳手架裡面強制檢測版本並要求使用者升級,否則使用者使用腳手架新建專案時,大概率可能用的是上次安裝時的版本。辛苦更新的功能沒法及時讓使用者使用上,非常尷尬。一個可能的解決辦法是要求使用者使用 npx 來代替 npm i -g

工程方案

Goofy Studio [1] 裡,我們給出的解決方案是「 工程方案 [2] 」。「工程方案」不單純是「腳手架」的升級版,而是一系列前端研發活動「最佳實踐」的沉澱。工程方案的「程式碼初始化配置」即涵蓋了「腳手架」的功能。我們提供了三種程式碼初始化方式,其實工程方案的程式碼初始化也是做了模板程式碼初始化,新建倉庫,push 程式碼等操作,與在本機執行腳手架並無大的不同。但是,工程方案的程式碼初始化完全是在雲端容器執行的,最大程度的避免了本地環境差異造成的失敗問題,且過程全自動,不需人工干預,大大節省時間。更妙的是,工程方案的專案建立可以一次性將各種服務(比如 SCM,GoofyWeb 部署等)及釋出流水線(比如 DevOps)建立好,專案建立完成後即可進行釋出。

模板方式

這種方式是最簡潔的,只需配置一個模板程式碼壓縮包(tar)即可,程式碼初始化時會直接將該壓縮包上傳到新建立的倉庫。

CLI 方式

這種方式會在一個容器裡執行設定好的命令以進行程式碼初始化,並將產物作為模板程式碼上傳到新建立的倉庫。這個過程各個環節均可配置,比如全域性安裝的包,執行的命令,產物的目錄,需要忽略的檔案及資料夾等。下圖是建立一個 Vue 專案的程式碼初始化配置。由於公司的編譯打包系統(SCM)通過配置檔案(scm_build.sh)來定義編譯過程,因此我們提供了 @byted/studio-cli 來生成該配置檔案。 上圖使用 -p default 生成了一個最簡單的 Vue 專案,但是實際業務中可能需要開啟內建的一些功能,比如 Vuex``babel 等。因此我們提供了 shema 輸入表單 來支援使用者在初始化時向 CLI 傳遞資料。為了便於演示,我們生成一個 Gulu 工程 ,並且提供模板選擇功能,部分配置如下圖: 為了能渲染出上圖中的模板選擇下拉選單,我們需要配置 schema:

{
"schema": {
"key": "gulu",
"isObject": true,
"items": [
{
"key": "template",
"label": "select template",
"type": [
"string"
],
"mutualExclusion": true,
"items": [
{
"key": "http-server",
"label": "http-server"
},
{
"key": "http-server-ts",
"label": "http-server-ts"
},
{
"key": "thrift-server",
"label": "thrift-server"
},
{
"key": "thrift-server-ts",
"label": "thrift-server-ts"
},
{
"key": "plugin",
"label": "plugin"
},
{
"key": "plugin-ts",
"label": "plugin-ts"
}
]
}
]
},
"customUIConfig": {
"template": {
"ui": "Select"
}
}
}

關於 schema 的語法規則,可以檢視 幫助 [3]

webshell 方式

此功能正在開發測試中,暫未開放。

為了進一步降低程式碼初始化的配置門檻,我們正在開發 webshell 方式,即不需要配置任何 schema 表單,只需要配置 cli 命令。執行程式碼初始化過程時,使用者可以直接在頁面的 webshell 上進行互動,完全模擬 CLI 在本機執行的過程。webshell 方式也會作為 CLI 方式的兜底,即使 CLI 升級了,增加了一些問題,但是 schema 沒有及時更新,使用者也可以在 webshell 裡完成新增的問題互動,成功進行程式碼初始化。

小結

使用工程方案的程式碼初始化配置來代替腳手架,使得每次建立專案時使用的都是最新版的 CLI,而且每次都在一個全新的容器裡進行,可最大程度提高程式碼生成成功率。

工程方案市場

前面說到「工程方案」是前端研發活動「最佳實踐」的沉澱,因此我們做了「工程方案市場」,將「最佳實踐」以實體的方式提供出來,任何人可以直接使用。將團隊定製的工程方案放到工程方案市場裡,一方面方便團隊的業務開發,維持技術的統一性,另一方面也可以向外輸出影響力。

附錄

  • Goofy Studio: 影片 [4]文件站 [5]嘗試使用 [6]

  • 工程方案: 文件站 [7]工程方案市場 [8]

  • 使用者群: Goofy Studio 使用者群 [9]

參考資料

[1]

Goofy Studio: https://studio.goofy.app/

[2]

工程方案: https://studio.goofy.app/docs/usage/solution/intro

[3]

幫助: https://studio.goofy.app/docs/usage/solution/code-init

[4]

影片: https://tech.bytedance.net/videos/6969820579922870302

[5]

文件站: https://studio.goofy.app/

[6]

嘗試使用: https://studio.bytedance.net/

[7]

文件站: https://studio.goofy.app/docs/usage/solution/intro

[8]

工程方案市場: https://studio.bytedance.net/solution

[9]

Goofy Studio 使用者群: https://applink.feishu.cn/client/chat/chatter/add_by_link?link_token=cbbo7f94-33d4-4222-86f2-a3acddd66a5b