Typescript落地和代碼自動化——前端穩定性和研發效率精進

釘釘前端團隊原創,點擊右上角關注咱們,瞭解更多前端技術前端

做者: 燭象java

引言

釘釘業務體量已達億級,釘釘技術的服務端、客戶端等的數據模型和接口已達到極高的複雜度。面對多樣的客戶端和技術棧IO環境,咱們採用了IDL(interface description language)來描述多端數據通訊的約定,以收斂業務複雜度帶來的維護風險。node

對於前端來講,容器環境從mobile、web到智能硬件IOT、桌面端CEF容器;上下游數據源也包羅了Java、C++、Node.js等宿主語言環境。 c++

前端模型

在多人協做、前端工程化的大背景下,咱們開始大量使用Typescript來加強代碼的健壯性、可維護性。本文將分享筆者是如何設計自動化代碼工具,以便加速typescript在團隊的落地。web

前端代碼演進至Typescript

相信大部分前端掘友們都有體感,業務迭代伴隨的數據接口、模型改動,都須要前端同窗手動檢查業務代碼,一旦改動不完全、單元測試沒有覆蓋分支流程,線上穩定性就極容易收到威脅,做爲開發的體感也是極差。typescript

在2017年,藉助釘釘桌面客戶端從node-webkit演進至native CEF架構的契機,咱們引入Typescript做爲開發語言,並逐步使用起ts的技術生態,如rxjs、redux-observable等。npm

從2017年到2018年,釘釘桌面客戶端CEF容器中運行的前端代碼就已經高達23萬行,維護者達到20位。redux

Typescript在釘釘桌面端的落地讓推廣工做獲得了承認,好比釘釘考勤在重構過程當中,逐步從js遷移到ts,開放平臺的售賣系統直接就用ts編寫、多個內部npm模塊編寫的語言選型優先採用ts。小程序

But , 本來覺得ts能夠在團隊順利推廣,然而現實卻並不是如此。不少新業務在選型時仍是選擇了js,是工程化成本過高仍是ts太難?設計模式

咱們瞭解到不少新同窗、實習生加入團隊就能很快的上手老的ts項目,斷言ts語言不是問題源頭。

在和業務開發同窗溝通後,咱們發現技術棧從js遷移到ts的過程當中,數據接口定義的編寫、ts腳手架的從新熟悉是主要的障礙源。

工程化和研發效率的問題構成了較高的ts研發成本,成本就意味着收益下降。

確實,要想享受ts的類型檢查類型推導編譯期代碼檢查等便利,前端項目就必須提供數據模型和接口的ts定義,咱們但願找到自動化生成ts代碼的方案來解決這個問題。

Typescript落地之IDL自動化生成代碼

在開始介紹咱們的IDL自動化代碼生成方案以前,我先簡單介紹下釘釘的IDL —— 強有力的多端數據接口描述語言。

背景知識之 釘釘IDL

釘釘的接口描述(IDL)文件,由model和interface組成,model用來描述數據模型定義、interface描述接口信息。舉個例子

/** * model.idl * 網關報錯返回對象 */
module test;

struct GatewayErrorModel {
    // 是否被降級。1是,0否
    1: int isDegrading;    
    // 安全網關域名
    2: string domain;
};
複製代碼
/** * interface.idl */
module test;
include test.GatewayErrorModel;

interface GatewayIService {
    /** * 上報網關訪問異常錯誤 * @param appId ID * @param host 域名 * @param errMsg 錯誤信息 */
    GatewayErrorModel testRpc(string appId,string corpId,string domain,string errCode,string errMsg);
};
複製代碼

以上兩個文件interface.idl和model.idl同屬一個模塊, 模塊名由module關鍵字指定即test,模型和接口的依賴關係經過include描述,數據結構經過struct描述。 model和interface的idl文件,組合構成該模塊對外暴露的數據接口。 在釘釘,IDL描述了各端的數據IO信息,不一樣代碼語言如Java、C++的rpc和推送模型的自動化生成基於IDL。IDL爲各端的代碼編寫提供了一致性保障,讓全部的數據和請求都有源可溯。

簡單介紹完IDL後,咱們迴歸上面的問題:如何下降ts對業務開發的成本。

想必大部分讀者已經猜到了,咱們的方案即是編寫工具將IDL轉譯成Typescript接口和模型定義,簡圖以下。

數據流

前端代碼自動化工具之 dingtalk-idl-ts

從信息熵的角度來講,IDL既然能覆蓋c++/java等語言的數據約定,它包含的信息確定足夠覆蓋前端Typescript的定義。

下面用一幅圖,簡示下dingtalk-idl-ts的實現細節流程。

首先從IDL作tokenizer到AST,再由AST作fs.writeFile生成初步的ts文件,隨之根據業務上層傳入的語言模塊要求(如es、cjs)生成不一樣的compilerOptions以供tsc命令調用,最後調用tsc命令行自動生成rpc代碼及模塊定義。有興趣的同窗能夠私信瞭解每一個環節的代碼實現。

tokenizer

有了自動化生成ts的工具還不夠?咱們要將穩定性的要求注入生成的ts產物

爲了讓數據模型生成的置信度最高,在自動化生成代碼的同時,dingtalk-idl-ts工 具對數據模型的property作了optional的處理。 所以任何一行業務層的代碼若是對模型的property selector沒有作保護,都沒法經過編譯。

數據模型

這樣的設計模式給業務代碼帶來了必定的冗餘度,但爲業務的正確運行和錯誤溯源作了底線的保護。

自動化代碼的生成產物,大體以下:

產物

經過dingtalk-idl-ts提供的命令行工具,業務開發只須要一個命令行,便可按需生成項目所須要的ts數據接口定義,從易出錯的手動編寫ts代碼中解放出來。

如今該工具已在釘釘的桌面端、小程序、H5應用中落地使用,ts的進一步推廣也隨着基礎設施的完善逐漸落地。

寫在後面

以上大體就是咱們在落地Typescript的一些方案和實踐,很是歡迎有更好想法的同窗提出意見和建議。但願讀完本文你有必定的收穫。

招人時間:

釘釘前端團隊社招全面開啓,求各路技術達人加入。

簡歷投遞郵箱: xiaogang.hxg@alibaba-inc.com

筆者釘釘號: huangxiaogang

掃碼關注更多釘釘技術

釘釘技術圈

😊釘釘歡迎掃碼關注《釘釘技術圈》

釘釘微信公衆號

😊歡迎掃碼關注《釘釘大前端團隊》微信公衆號

相關文章
相關標籤/搜索