當前位置:
首頁 > 科技 > 谷歌為何會選用TypeScript?

谷歌為何會選用TypeScript?

作者 | neugierig(谷歌開發者)

譯者 | 無明

出處 | 前端之巔公眾號

我已經使用 TypeScript 兩年多時間,是時候寫一兩篇文章來總結一下了。

谷歌在很早之前就張開雙臂擁抱 Web 應用程序,Gmail 已經發布 14 年了。當時,JavaScript 的世界是瘋狂的。Gmail 工程師不得不為 IE 糟糕的垃圾回收演算法捏一把汗,他們需要手動將字元串文字從 for 循環中提取出來,以避免 GC 停頓。最近,我找到了那個時代一個設計文檔,是關於如何「minify」 JavaScript 文件的,只不夠一些工具僅用於 Windows 平台。這些事情在今天看來是難以想像的。

多年來,谷歌構建了大量的基礎設施,用於開發大型的 JavaScript 應用程序。例如,他們開發了一個模塊系統,可以讓源文件自描述它們之間的相互依賴關係,還有一個捆綁器,可以將源文件合併在一起,並縮小為可與瀏覽器兼容的工件。另外還有一個工具,它通過動態載入入口點來分析應用程序的依賴關係圖,並抽取服務的公共子模塊。還有非常常見的伺服器端渲染。所有這些概念對於今天的 Web 開發人員來說都是很熟悉的,但谷歌的技術棧總是很超前,它們並行演進,雖然在概念上很相似,但實際上卻完全不同——不同的流程、工具,甚至名字都不一樣。

另一個有關並行演進的例子:谷歌、Facebook 和微軟各自構建了相似但不兼容的編譯器,這些編譯器向 JavaScript 中加入了靜態檢查。谷歌的編譯器通俗地稱為 Closure(不要與 Clojure 這門編程語言混淆,另外請注意,ClojureScript 使用的是 Closure 編譯器)。

谷歌的 JavaScript 技術棧非常棒,其中一些部分已經超越了當今最好的技術。例如,Closure 編譯器可能仍然是最複雜的 JavaScript 優化器,可以使用類型信息來優化代碼、跨熱載入塊邊界進行函數內聯,以及將無用的代碼剝離成單個符號。

當然,谷歌的 JavaScript 技術棧也存在一些問題。Closure 是 JavaScript 的一種帶有靜態類型的變體,通過注釋來引入語言新特性。Closure 具有不可預測的語義,它運行速度慢,容易出現 bug,除非你很小心,否則它很容易就讓你的代碼變得一團糟。它是開源的,但除了一些能夠招到谷歌前員工的公司之外,行業中很少有公司會使用它。在谷歌內部,我認為 JavaScript 的聲望並不高,部分原因在於我們的工具,它將靜態語言的冗長性與動態語言的不可預測性結合在了一起。

而在谷歌之外,JavaScript 在不斷演進,變得越來越流行。為了解決 IE 垃圾回收器的問題,我們開發了 Chrome,然後 v8 出現了,繼而 nodejs 誕生,所以今天的大多數 Web 工具都是用 JavaScript 編寫的。模塊系統(UMD、AMD、CommonJS)大肆膨脹,ES6 也發明了自己的模塊系統,但由於某種原因,與其他模塊系統不兼容,非常可惜。npm 統一了工具和庫的共享方式。Webpack 可以在你開發代碼的同時將模塊動態載入到正在運行的應用程序中。

但谷歌沒有使用這些東西。我們有一個類似 SASS 的 CSS 預處理語言,只是它不叫 SASS,而且沒有人喜歡用它。花哨的塊分割器並不支持第三方 JavaScript 庫,部分原因是這些工具的出現早於 JavaScript 的庫生態系統。

這些都已經成為歷史。你可以說我們不應該忘了我們是如何到達這裡的,但不管怎樣都無法改變我們已經達到這裡的事實。或許我們更應該關心接下來要去哪裡。我們有幾個選擇。

第一個選擇是放棄這個已經破敗不堪的星球,去到一個沒有 JavaScript 的新星球。如果我們在 GWT(一個將 Java 編譯為 JavaScript 的谷歌項目)或 Dart(一個將其他語言編譯為 JavaScript 的谷歌項目)或 WASM 或(Clojure?Haxe?Elm?)上做更多的投入,根本就不需要擔心 JavaScript!

作為編程語言愛好者,我覺得這個主意不錯。不過長話短說,這裡有一些問題:首先,採用不同的語言對於我們現有的數百萬行代碼來說並沒有任何意義——「使用新語言重寫」在某些情況下可能是正確的選擇,但很難做到充分利用 Gmail 工程師的時間。其次,採用不同的語言對於我們想要聘請的前端程序員來說一點幫助都沒有,等於說他們之前的經驗都用不上了。

改變一切的對立面是不做出任何改變。JavaScript 世界充斥著業餘代碼和 leftpad 災難。一個優秀的工程師總能適應特殊的前端開發方式,我們總能改進或構建更多屬於自己的工具。我們構建的應用類型——谷歌搜索主頁每天的點擊量超過數十億次——與其他人構建的網路應用程序不同,我們的工具不僅優秀,而且都是必需的。我認同這種觀點。我認為存在某種權衡,一方面,構建我們自己的工具是有意義的,另一方面,我們已經遠離了主流,以致於我們的工具變成了一種負擔。關鍵在於,我們現在處於這個權衡的哪個位置上,我相信我們離後者更近。我們從對 LLVM/Clang 的貢獻中獲益,因為我們依賴於 C++,但是我們不會從構建自己的 LLVM 中獲得更多額外的價值。

我的團隊一直在追求中間那條路:在必要的時候逐步採用一些外部工具。這項任務並不那麼有趣——我們不可能只是簡單地把遺留的那套東西直接丟掉——但我喜歡謙虛一些,向外看,而不是向內看。

在谷歌 JavaScript 孤島和大陸之間架起橋樑的首先是一個靜態檢查器:

(1)它不是我們內部開發的

(2)已經很流行,與我們現有的代碼相似

(3)旨在為 JavaScript 做橋接

(4)支持大規模開發

這個工具就是 TypeScript。Closure 編譯器的優勢在於它的優化輸出,而 TypeScript 具有出色的用戶介面,但不提供優化。這兩個工具是互補的,並且在處理某些任務時可以進行分層式協作。

使用 TypeScript 給我們帶來了很多好處——從 IDE 風格的代碼完成到從 StackOverflow 上獲取相關問題的答案。我們所要做的工作主要是集成:將我們的應用程序逐步遷移到 TypeScript,而不是從頭開始重寫。

在與谷歌範圍內的構建系統集成時,我們非常謹慎,我們進行增量編譯,這對大型應用程序來說至關重要。一個模塊發生變更,只要不影響公開的 API,就不應該導致下游模塊進行重新編譯。與 Closure 類型 / 模塊系統的集成意味著 ES6 TypeScript 模塊可以導入谷歌模塊系統模塊,反之亦然,而且可以保留大部分類型信息。

在谷歌,現在到處都可以看到 TypeScript 的身影。如果你在使用谷歌的產品,很可能是在與 TypeScript 代碼打交道。TypeScript 本身就是一系列有趣的方案的折衷,它在靜態類型的編程語言與自由轉換的 JavaScript 生態系統之間做出了權衡。這就是我們的工程師要做的事情:做出有趣的權衡,嘗試在各種問題之間找到平衡點。我希望後面能夠寫更多文章分享這些年發現的一些有趣的事情,我認為 TypeScript 在這個領域內達到了很好的平衡。

英文原文

http://neugierig.org/software/blog/2018/09/typescript-at-google.html


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 InfoQ 的精彩文章:

43億歐元罰款後,谷歌警告安卓可能不再免費;JDK 12早期試用版發布;微軟正為Linux用戶改進Windows命令行
1小時串講人工智慧必備基礎模型

TAG:InfoQ |