作者 | 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

谷歌为何会选用TypeScript?相关推荐

  1. 前端一年精选好文,请打包带走

    新的一年,小编为大家整理了过去一年以来前端之巅发布的 130 多篇精选好文,点击文章标题即可跳转到原文,请速速收藏哦~ 一.前端动态 版本更新 ECharts 4.0正式发布了! Dart 2正式发布 ...

  2. 谷歌大脑发布神经网络的「核磁共振」,并公开相关代码

    作者:杨晓凡.camel.思颖.杨文 神经网络的可解释性一直是所有研究人员心头的一团乌云.传统的尝试进行可解释性研究的方法是通过查看网络中哪个神经元被激发来来理解,但是即使我们知道「第 538 号神经 ...

  3. 尤雨溪回应:Vue与TypeScript为什么相性特别差?

    近日,有开发者在知乎上提出了一个问题:"TypeScript 不适合在 vue 业务开发中使用吗?",Vue的作者尤雨溪针对这一问题发表了自己的看法,也解释了Vue 3.0选用Ty ...

  4. 作为前端开发,如何高效学习 TypeScript

    大家好,我是若川.有朋友跟我说最近面试前端候选人,问到关于 JavaScript 的一些少见误区问题,候选人很多都没回答上来,他很诧异,一个从国际大厂出来的面试者,竟然对 JavaScript 的一些 ...

  5. typescript map转对象_TypeScript 快速上手及学习笔记 - JoeYoung

    TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript. TypeScript可以在任何浏览器.任何计算机和任何操作系统上运行,并且是开源的. 什么是 TypeScr ...

  6. TypeScript是什么,为什么要使用它?

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://medium.com/swlh/what-is-typescript-bf333e ...

  7. 白鹭安装node_Egret Engine(白鹭引擎)介绍及windows下安装

    Egret Engine简要介绍----- Egret Engine(白鹭引擎)[Egret Engine官网:http://www.egret-labs.org/]是一款使用TypeScript语言 ...

  8. 最适合微服务的7大编程语言

    摘要:本文中,将介绍微服务项目中常用的7种语言,并通过几个因素对比一下,包括技术方面的考虑.社会(生态系统)方面的考虑以及经济方面的考虑. 微服务是一种架构风格,通过一组服务构成应用程序,这些服务具备 ...

  9. Angular 2 Output

    Angular 2 Output Output 是属性装饰器,用来定义组件内的输出属性.在 Angular 2 Input 文章中,我们介绍了 Input 装饰器的作用,也了解了当应用启动时,Angu ...

最新文章

  1. 中电信抢滩云计算 在上海开建“信息银行”
  2. 网络营销再掀波澜,微博独领风骚
  3. 新的一年,努力努力!
  4. 【Python】电商用户复购数据实战:图解Pandas的移动函数shift
  5. 51nod 1575 Gcd and Lcm
  6. day-17 包与模块
  7. 提升速度与精度,FedReg: 减轻灾难性遗忘加速联邦收敛(ICLR 2022)
  8. UI设计灵感|逻辑感十足的数据可视化界面设计
  9. Azure HDInsight与Hadoop周边系统集成
  10. 题目1088:剩下的树(小端快排+大端判断边界)
  11. elk日志收集系统 linux_ELK 日志分析系统
  12. java swing 雪花_求用JAVA制作的飘雪花的效果
  13. oracle生成测试数据的简单方法
  14. c#语言程序设计pdf,C#程序设计及应用教程(第2版)
  15. 小学生python游戏编程6----碰边变颜色的小球
  16. 墨卡托坐标系和gcj03坐标系转换
  17. 苹果开发者 - 添加App
  18. 反编译so库破解so
  19. KaLi Linux 2019.2安装netspeed
  20. 【BBC纪录片】无人驾驶汽车的黎明(观后总结)

热门文章

  1. 有关文档碎片(document fragment)的用法
  2. LeetCode--84.柱状图中最大的矩形(暴力法,单调栈)
  3. 2015中缀表达式转化为后缀表达式(C++,附思路,注释多)
  4. c语言实现路由功能,前端路由的两种实现方式,内附详细代码
  5. c语言程序设计电大形考作业答案,2016年电大-电大c语言程序设计形成性考核册答案(-).doc...
  6. php 价格计算方法,PHP算法逻辑:如何计算购买量?
  7. pythontkinter真实的例子_Python Tkinter真实的例子
  8. Tornado 错误 Global name 'memoryview' is not defined
  9. 教你实现图片的惰性加载
  10. jsp:include