SAP UI5 未來發展的趨勢之一:擁抱 TypeScript

注销發表於2022-02-15

這是 Jerry 2022 年第 3 篇原創文章,也是本公眾號第 371 篇原創文章。

近年來,前端開發領域迅猛發展,各種新技術、新框架、新工具和新的開發理念,層出不窮。另一方面,前端應用的規則和複雜度也大大增加。雖然 JavaScript 已經成為 Web 前端開發最普遍使用的程式語言,但 JavaScript 誕生之初,並不是為了開發超大規模的複雜前端應用而設計的。作為一門動態型別程式語言,JavaScript 缺乏型別檢查支援,使得許多程式碼問題直至執行時才能被發現,降低了專案開發效率,使其在開發複雜前端應用時顯得力不從心。

正因如此,越來越多的現代前端開發框架,比如 Angular,React 和 Vue,都引入了對 TypeScript 的支援。

TypeScript 出身名門,是微軟 2012 年推出的一門靜態型別程式語言,屬於 JavaScript 的超集,可以編譯為 JavaScript 執行。

TypeScript 的最大特點就是靜態型別和從語言層面對 ECMAScript 6 標準的原生支援。

基於 TypeScript 開發的前端應用,在編譯期就能進行型別和語法檢查,提高了程式碼的健壯性和可預測性,降低了專案維護成本。TypeScript 對模組、名稱空間和麵向物件的原生支援,也有助於降低大型複雜前端應用的專案組織和管理成本。

讓 Web 開發人員如虎添翼的是,現代流行的 Web 開發工具比如 Visual Studio Code,WebStorm,Atom 等等,均對 TypeScript 提供了非常完善的支援。

TypeScript 在 SAP 產品開發中的一個成功案例

以 Jerry 所在 SAP 電商雲 Spartacus UI 開發團隊的工作為例,到 2022 年 1 月,Spartacus 最新的版本為 4.3.0:

https://github.com/SAP/spartacus

總共有效程式碼數已經超過 35 萬行,ts 和 html 檔案個數超過 5000 個。

Spartacus 選擇的開發語言正是 TypeScript,歸功於前文所述 TypeScript 的諸多優點,我們團隊的開發效率絲毫沒有因為應用本身的複雜度而降低。

作為另一個誕生已經十餘年的企業級前端應用開發框架,SAP UI5,也從 2021 年開始,引入了對 TypeScript 的支援。時至今日,這一支援工作仍然在進行中,最新進展可以從 SAP 官網獲得:

https://sap.github.io/ui5-typ...

本文透過一個實際的 Hello World 級別的 SAP UI5 應用,介紹 SAP UI5 如何引入對 TypeScript 的支援。

新建一個空的資料夾 ts-ui5. 因為我們要藉助 npm 來安裝和 TypeScript 開發相關的依賴,所以首先使用 npm init 建立一個空的 Node.js 專案。該命令列會生成一個預設的 package.json 檔案。

新建一個 src 資料夾,裡面放置一個 Component.ts 檔案,程式碼如下:

在這段程式碼裡,我建立了一個新的 Component 類(第6行),其父類為 SAP UI5 標準的 UIComponent.

這裡我們初次領略了 TypeScript 靜態型別檢查的風格:Visual Studio Code 抱怨找不到 sap/ui/core/UIComponent 這個 module 以及其型別定義。

這正是意料之中的錯誤,因為 TypeScript 本身是無法識別 SAP UI5 那一套型別定義的,為此我們需要手動將 SAP UI5 框架完整的型別定義系統,匯入我們的 TypeScript 專案。

使用如下的命令列匯入 SAP UI5 為 TypeScript 提供的型別定義:

npm install --save-dev typescript @types/openui5@1.97.0

安裝完之後,上述編譯錯誤就消失了。

我們透過命令列 npm install 為 TypeScript 安裝了針對 SAP UI5 所謂的 DefinitelyTyped(外部型別定義). SAP UI5 開發團隊基於 SAP UI5 JSDoc 生成了一套 TypeScript 能夠識別的外部型別定義,這樣 TypeScript 可以依據這些型別定義,進行編譯期的靜態型別檢查。

SAP UI5 開發團隊為 TypeScript 製作的外部型別定義釋出在如下的公網可訪問的 Github 倉庫裡:

https://github.com/Definitely...

npm install 之後,這些型別定義檔案,以 d.ts 格式的檔案形式,出現在工程的 node_modules\@types\openui5 資料夾內。這些檔案也是 TypeScript 對 SAP UI5 應用程式碼進行語法檢查的基礎。

因為瀏覽器無法直接執行 TypeScript,因此我們需要使用 TypeScript 的編譯器 tsc,將 Component.ts 編譯成 JavaScript 程式碼。

為 TypeScript 編譯器建立一個配置檔案 tsconfig.json, 這個檔案的作用是提供更詳細的編譯選項,比如透過將 target 欄位維護成 es2015,從而指定編譯出來的 JavaScript 檔案支援 es2015 的語法特性,編譯的輸入目錄為 src,輸出目錄為 dist.

ES2015 是 ECMAScript 6 的第一個版本,於 2015 年 6 月釋出,正式名稱為 ECMAScript 2015 標準,簡稱為 ES2015.

tsconfig.json 檔案維護好之後,執行命令列 npx tsc 進行編譯。

成功編譯之後,在資料夾 dist 裡生成了一個新的 Component.js 檔案,其 JavaScript 語法支援 ES2015 特性。

對於很多 SAP UI5 開發人員來說,可能更習慣使用傳統的 UIComponent.extend("ui5.typescript.helloworld.Component") 方式來定義 Component,而不是下圖基於 ES2015 的 extends 語法。

另一方面,並不是所有的瀏覽器都支援 ES2015,我們也不應該強迫客戶升級其瀏覽器到能夠支援 ES2015 的版本:

因此我們可以使用 Babel 這個工具,將 ES2015 版本的 JavaScript 程式碼,轉譯成低版本的傳統 JavaScript 程式碼(比如 ES5 ).

使用命令列安裝 Babel 轉譯器的相關依賴:

  • npm install --save-dev @babel/core @babel/cli @babel/preset-env
  • npm install --save-dev @babel/preset-typescript babel-preset-transform-ui5

同樣為 Babel 建立一個配置檔案 .babelrc.json,透過 presets 陣列裡的記錄,告訴其執行轉譯操作的具體細節:

執行下列命令列,使用 Babel 進行 JavaScript 的轉譯操作,輸出資料夾指定為 webapp:

npx babel src --out-dir webapp --extensions ".ts,.js"

轉譯完成後,輸出資料夾 webapp 裡出現了一個 Component.js, 其原始碼就是 SAP UI5 開發人員熟悉的 UIComponent.extend 這種傳統語法了。

SAP UI5 開發團隊已經事先準備好了一個用於學習的 Github 倉庫,裡面包含了採用 TypeScript 開發好的一個 SAP UI5 Hello World 應用的原始碼:

https://github.com/SAP-sample...

我們把該倉庫的 src 資料夾裡的全部內容,複製到本地 src 資料夾。

下圖是使用 TypeScript 開發的 App Controller 程式碼:

(1) 從 sap.ui.core.d.ts 提供的外部型別定義裡,匯入 Controller 類定義

(2) 定義一個新的 App 類,繼承自 SAP UI5 標準的 Controller 類

(3) 過載 Controller 類定義的兩個 public 方法

是不是覺得 TypeScript 這種純粹物件導向的程式碼編寫方式,可讀性要優於傳統 ES5 的 JavaScript 程式碼呢?

歸功於 SAP UI5 團隊提供的外部型別定義,此刻我們就可以在 Visual Studio Code 這種本地開發環境裡,享受到原本只有在 SAP WebIDE 和 SAP Business Application Studio 等線上開發環境裡才能支援的語法檢查和程式碼自動完成提示等功能了:

TypeScript 開發結束之後,使用開源的 SAP UI5 Tools(@ui5/cli) 這個工具進行構建和本地啟動。

為此,首先安裝 SAP UI5 Tools 的依賴:

npm install --save-dev @ui5/cli

同樣我們需要為 @ui5/cli 建立一個配置檔案 ui5.yaml,提供具體的構建選項。

使用下列命令列,將 src 資料夾裡的 TypeScript 程式碼,透過 Babel 轉譯成傳統的 JavaScript 程式碼,放置於輸出資料夾 webapp 內。

npx babel src --out-dir webapp --source-maps true --extensions \".ts,.js\" --copy-files

上述命令列裡兩個選項的解釋:

  • source-maps true: 生成 .map 原始碼對映檔案,這樣我們就可以直接在 Chrome 開發者工具裡,給原始的 TypeScript 程式碼設定斷點並單步除錯。瀏覽器實際執行的是 babel 轉譯後的 JavaScript 程式碼。透過這些 .map 對映檔案,Chrome 開發者工具會自動幫助我們將當前執行到的 JavaScript 程式碼對映成原始的 TypeScript 程式碼。
  • copy-files:對於所有字尾非 .ts 的檔案,直接從 src 資料夾複製到 webapp 資料夾,比如這個專案裡所有的 xml view 檔案。

babel 生成的 .map 原始碼對映檔案:

最後透過命令列本地啟動這個 SAP UI5 應用:

npx ui5 serve -o index.html

外觀如下:

Chrome 開發者工具 Sources 標籤頁裡開啟後,看到的是原始的 TypeScript 檔案,可以直接設定斷點,單步除錯:

關於 SAP UI5 對 TypeScript 支援工作的最新進展,請持續關注 SAP 官網:https://sap.github.io/ui5-typ...

感謝閱讀。

更多Jerry的原創文章,盡在:"汪子熙":

相關文章