我用 TypeScript 語言的七個月

發表於2013-07-19

【感謝@Little2Mao 的熱心翻譯。如果其他朋友也有不錯的原創或譯文,可以嘗試推薦給伯樂線上。】

從2012年12月開始,我用 TypeScript 作為主要語言,用於一個大規模的企業專案。專案下個月要釋出了,我想分享一些細節內容,包括我們團隊怎麼使用 TypeScript 的,還有成就專案的工作流程。

 

什麼是TypeScript

TypeScript是由微軟開發的一個能夠在Node.js上執行的開源語言和編譯器。這個語言是在ECMAScript6基礎上演化並吸收了生成Javascript類別和介面的一些特性。Typescript 的編譯器使用TypeScript語言編寫,並且能夠在任何相容Javascript的程式內執行,同時它也是作為node.js的一個工具包釋出的。所以該語言最終生成的仍然是Javascript指令碼。

 

評估

在2012年十一月期間,我們發現我們所選擇的開發工具和對於Typescript的試用確實給團隊帶來很多便利。起初,我們試用了Haxe,Dart,Coffescript等一系列語言,但是我們最終還是被擁有ECMAScript6特性Javascript編譯器:Tyepscript打動了。我們所期望的是使用Javascript作為開發語言但同時又想要在我們的開發過程中注入一定的結構框架,而且希望能夠依靠編輯器來進行一些糾錯和驗證。所以實際上我們最終還是隻有在Javascript和Typescript之間作選擇。在這基礎上,團隊作了幾個小型的專案雛形,並且迅速發現了以下一些有趣的特性:

驗證:Typescript能夠在編譯的同時讓我們驗證一些程式碼在不同模組中的重複使用。在宣告變數型別和定義語句方法的時候,我們能夠很有效的對所有call/get/set的使用在所有模組中進行交叉驗證。如果一個屬性被賦給了bbox.controls.image類,那麼在編譯時只有圖片例項或其子類才能夠滿足編譯條件。

報錯:Typescript編譯器能夠提供非常細節的報錯,如果提供額外的類和介面資訊,那報錯的內容會更加的詳細。

輕量化:Typescript的類和介面在編譯時會蒸發的一乾二淨從而生成純淨的Javascript指令碼。

ECMAS6(ES6):Typescript在ES6的基礎上新增了類和介面。它讓我們能夠利用最新的Javascript語法規則去編寫程式同時在編譯時新增ES3,ES5的標籤,使得其能夠相容ES3,ES5的標準。這讓程式碼的整理變得非常輕鬆。

Build process:在我們最初的檢驗和測試過程中,有一個部分是利用Ant建立一個團隊程式。通過對環境的適當除錯,開發者能夠和SCM(架構部署)進行同步並且建立一個擁有所有程式碼元件(codepakages)的本地伺服器用於開發和除錯。整個建立的過程遷入了LESS,RequireJS,Uglify2,TypeScript,模板處理和伺服器的生成。

 

使用

在評估之後的幾個月裡,我們基於TypeScript建立了一個穩定的團隊工作流程並且從中獲利良多。程式的建立(buildprocess)是我們開發過程中一個至關重要並且每天都會使用到的一個過程。基於TypeScript,我們每天的工作流程基本上如下所述:

  • 從SCM進行更新
  • 執行‘antall’==>建立全部+執行本地伺服器
  • 執行’antdev’或者’antts’==>增量式建立
  • 檢校建立過程中的錯誤或者在瀏覽器中進行測試
  • 清理bug然後重複以上步驟

我個人非常喜歡這樣的運作模型,從中我發現我們花在瀏覽器測試階段的時間遠少於之前的JavaScript專案。由於Build過程中就已經檢校了一些介面/型別/語法的錯誤,因此在瀏覽器測試階段我們就減少了對此類錯誤的勘誤工作量。一旦所有人都熟悉了TypeScript的debugging流程,我們大大的提高了工作效率,這是在以前的開發過程中所沒有體驗過的。花了5秒鐘編譯但是最終卻刪除了整一個沒有運作的毫無意義類聽起來有點不能接受。這種防患於未然的debugging方式節省我們大約2個月的時間,而且程式碼的質量也大大提高了。

當初在我們進行開發的時候,TypeScript定義檔案的質量和內容不是非常理想。定義檔案能夠讓你非常安全的從外部定義JavaScript的介面型別,但這樣做你的程式碼必須在編譯時完全遵照定義檔案。自從這個專案開始之際,我們借DefinitelyTyped專案為一些主要的或者非主要的JavaScript庫編寫潤飾了180個定義。小組最後在建立程式時使用了關於Require,JQuery,Backbone,Bootstrap,Underscore和EaselJS的定義檔案。現在為TypeScript新增定義檔案,你只要在你的main.ts檔案中新增一下的程式碼就可以了。

根據同樣的方法你也可以向TypeScript中新增一些外部庫。某種程度上來說定義檔案,介面和TypeScript的類的運作方式是類似的。為了簡化我們建立程式的過程,我們將這些呼叫過程全部綜合到一個init.ts檔案中,這樣當編譯器工作的時候就可以自動載入所有該應用所需要TypeScript程式碼。哪怕是那些本需要通過先呼叫模組才能呼叫的類也能在這裡被呼叫表達,這樣這些類就會在編譯時預先在外部生成一個模組檔案以供使用。注意這個外部模組的程式碼中”exportClass”的語法,它會告訴編譯器將檔案視為一個外部模組進行呼叫,而編譯器標識”-moduleamd”會使得編譯器將模組編排成AMD或者CommonJS的格式

除此之外,TypeScript還有另外一個很優雅整合程式碼的功能。每一個類和變數都被輸出到瀏覽器視窗實體之外的一個路徑裡以供全域性訪問。我們使用了bbox作為所有類和變數的名稱空間,同時提供了輸入時的支援,你也可以便捷的為你自己的應用建立一個良好名稱空間。以上的模組包含在了”bbox.controls”裡並且在執行時可以發現它被輸出到了bbox.controls,Bounds中。考慮到我們有用到大約60多個類,我們最大化的使用了這個模組系統並且在開發過程中使用的非常順利。你可以遵照這個方法自由的匯出和類別化你自己的變數或者所有的類,而不需要讓所有的變數都歸屬於某個類。由於提供了類別和許可權的限制,類別化輸出的變數對於模組內單一的變數非常適用。隨著類別和模組的介入,你使用JavaScript的方式也會有所改變,並且很難形成比較差的實踐方式。隨著一個能夠監測到通過陣列或者一個很特殊的類別重寫了某實體的高階編譯器,你可以一不同的方式利用JavaScript進行開發,TypeScript作為一種語言有著它獨特的工作模式。它已經不完全是JavaScript了,但全包含了JavaScript原有的所有特性。

通過一系列的開發實踐我發祥我自己已經通過對程式碼的重構實現了開發策略的轉換。由於有時需檢查在不同部分受到修改影響的程式碼,我開始在有意識的改變變數類別,介面和名稱空間等方面相信編譯器本身的行為。在編譯之後我才會修改結果,並且根據需要進行程式碼的重構。這在很多方面都使我能夠很有效處理較大的程式碼量。編譯器為我省去了很多debugging的負擔。

至於我的開發環境,儘管其他團對成員選擇了Jetbrians,我依然選擇了sublimetext2+TypeScirpt語法高亮。毫無異議,我發覺即使沒有自動完成的功能,sublime依然能提供很好的TypeScript開發環境。由於TypeScript編譯器本身就有著增量式的編譯功能和豐富的IDE整合功能,可能需要更多的時間來證明到底Sublime/Edge/Jetbrains哪一個才是最適合的開發工具。

最後,當我愛上使用TypeScript的同時(當然,我也會繼續用下去),我發現了一個令人望而生畏的地方。有很多次,當你一頭扎進編譯環境中,編譯器卻由於輸入資訊不可用而阻止你呼叫一個方法或者變數。每當這時,我們發現只有我們手動修復bug時,利用關聯陣列語法(associativearraysyntax)去解決這個問題。比如:無論什麼樣的分類形式,foo[‘myProperty’]foo[‘myMethod’]() 應該能夠讓你介入foo的myProperty和myMethod屬性。這看起來有一些不可思議,但只要記住隨時可能用到關聯陣列語法(associativearraysyntax)就萬事大吉了,你總有需要它的地方。

最後附上一些專案開發過程中的總結資料:

  • 63個typescript類
  • 12個執行庫(libs)(Underscore,Require,Bootstrap,Jquery,Backbone,EaselJS…)
  • 一次建立所有程式,用時8秒
  • 一次建立所有開發程式,用時5秒
  • 149Kb大小的執行庫檔案和411Kb大小的類檔案

總結

在過去7個月裡用TypeScript做開發是一件非常愉快的事情。在之前的開發經驗裡,我使用過ActionScript/ES4,但由於有著相似的結構,我很快就適應了TypeScript,同時保持了JavaScript 優雅的程式碼便捷性。在很多方面,我發現對於TypeScript的使用,的確使我們在團隊程式碼質量和截止日期上有了很大提升。我不認為我是微軟的死忠,但是TypeScript確實使我眼前一亮。它是過去三年裡我所接觸的最好的也是比較容易接受的一個網頁開發的工具。我期待在未來能夠在更多的專案中用到,並且能夠參與到該語言/編譯器的開發中去。

這周我將會在舊金山的Build去了解TypeScript0.9的一些特性,下個月我會在Senchacon360Stack

我愛TypeScript!

Ted

相關文章