JavaScript的中年危机
摘要
本文讨论了尽管有尝试取代JavaScript,但它依然保持持久流行,以及当前工具链的重写强调速度和简洁性,突显了其普遍性与开发者体验不断演进之间的紧张关系。
暂无内容
查看缓存全文
缓存时间: 2026/09/22 21:55
# JavaScript的中年危机
来源:https://maroun-baydoun.com/blog/javascript-midlife-crisis
不久前,我在领英(https://www.linkedin.com/posts/marounbaydoun_all-the-javascript-building-tools-are-competing-activity-7250129195257782273-xIpX)上半认真半开玩笑地提了一个观察。
所有JavaScript构建工具都在比拼谁使用的JavaScript最少。(https://maroun-baydoun.com/static/6eb8402112f551e0e857734f4310c954/89c06/linked-in-quote.jpg)
一场彻底重写JavaScript工具链的浪潮席卷而来。那些曾帮助巩固该语言在我们技术栈中地位的老旧工具变得不再时髦,甚至备受质疑。其迟缓的性能被指责拖慢了数百万行代码的生产部署进程。追踪技术前沿的"弄潮儿"变得愈发困难。它们的名字或许不够响亮,但承诺却令人心动:速度,且是极快的速度。
这是一个对JavaScript开发者而言颇为奇特的时代。这门语言从未如此无处不在,却又似乎在自己的大本营逐渐失势。工具变得更快,配置更便捷,抽象层更厚实。我们编写的代码更少,配置更省,等待时间更短。但与此同时,我们打包、发布和紧急修复的频率却更高了。代码与最终产品之间的过程,正变得越来越容易被忽视。
所有性能基准测试都显示一片飘红向好。折线图或升或降或横盘——只要指向更少的凌晨三点紧急电话,就是好趋势。那么,我为何还要在此煞风景呢?
## 这门"不死"的语言
对于一门据称仅用十天写就的语言,JavaScript完成了不可思议的壮举。它逃离了诞生之地——浏览器,开始吞噬周围的一切。反应可想而知:*"哪个头脑正常的人会用JavaScript编写服务器和工具?"*结果证明,千千万万人都会。JavaScript登上了手机、游戏机、微控制器乃至你的冰箱。只要设备能理解二进制位,就能运行JavaScript。
尽管大受欢迎,JavaScript的道路却从来坎坷。诞生不久后,试图修复甚至彻底取代它的尝试就已悄然启动。微软为Internet Explorer配备了VBScript和JScript——他们自己的JavaScript变体,注意不是J-Pop和JRPG。在90年代,任何以J开头的名字听起来都更酷。Macromedia(后来是Adobe)用Flash开场动画和ActionScript驱动的游戏充斥了互联网。Google曾押注Dart作为Chrome的未来,后来却将其降格为Flutter的专属。
CoffeeScript等项目为JavaScript之杯增添了些许语法糖。当我们不再试图替换JavaScript时,又忙于从外部为其打补丁。jQuery统一了浏览器间几乎无法对话的Web平台。Lodash填补了语言在数组和对象处理上的明显空白。Moment.js让日期处理成了"别人的麻烦"。
JavaScript并未坐以待毙,任人图谋取代。在它单线程的框架内,它其实相当忙碌。浏览器厂商、标准组织和社区持续推动着这门语言前进。ECMAScript版本带来了期待已久的语言特性。TC39不断推出新提案,浏览器也逐渐学会就JavaScript应有的行为达成共识。随着时间推移,其标准库不再那么寒酸得令人尴尬。
然后TypeScript来了,JavaScript似乎终于被端上了银盘。或者看似如此。Typecript在其他尝试失败的地方取得了成功,它接受了一个不便的事实:JavaScript不会消失。
你可以改进它、隐藏它、编译成它,或者抱怨它。你就是无法摆脱它。
## 我们正在放弃的超能力
一统天下的语言既是恩赐也是诅咒。我们花了几十年讨论这个诅咒。在某个时刻,我们却忘了这个恩赐。
随着JavaScript持续扩散,它开始"自食其力"。Node.js催生了一批工具涌现并征服了生态系统。代码检查器、打包器、格式化器和测试运行器,与它们所检查、打包、格式化和测试的代码说着同一种语言。
如果(或者说当)工具链中某个环节出了问题,普通的JavaScript开发者能够检查代码。或许他们能理解这个Bug。如果他们睡足了八小时,或许能修复它。如果他们好胜心起,或许会提交一个拉取请求。至少,他们对这门语言有足够的了解,可以自信地将Bug归咎于维护者。
这种熟悉感的传承效果出奇地好。同一门语言跟随着开发者从浏览器到服务器,最终遍布几乎所有的领域。JavaScript加速了全栈工程师,或者说"全生态工程师"的崛起。是否有人能真正精通技术栈两端而不沦为"半神",这是另一个话题。但JavaScript确实使这种转型变得相当容易。工程师可以将他们对调用栈、基于原型的继承以及`typeof null === "object"`这一不幸事实的理解,带到几乎任何项目中。
人们围绕这个万能生态系统建立了整个职业生涯和企业。其中大部分曾经是且至今仍是开源且*免费*的,这无疑助益良多。
JavaScript赢得了浏览器战争,并在其他几场关键战役中取胜。然后Rust等新贵出现,准备领取奖杯并拍摄纪念照。
## 为毫秒而战
Rust、Go和Zig正接管JavaScript工具链中越来越大的部分。原因显而易见。
它们很快。真的很快。
> 我们正在用Rust编译JavaScript,以产出在主要用C++编写的引擎中运行的JavaScript。
没人愿意盯着构建进程看足够久以至于对进度条产生情感依赖。但是,当一个已经很快的工具的替代品宣称自己快十倍时,我开始琢磨:我们该用它刚刚还给我们的那些宝贵毫秒做些什么呢?
多喝一口咖啡?
更重要的是,我们为了这速度付出了什么?
用Rust重写打包器,你不仅让它更快了。你也缩小了能维护它的JavaScript开发者群体。新工具看起来依然像鸭子,叫声也像鸭子,但它完全是另一种野兽。它的内部机制隐退到一个更少人拥有钥匙的黑盒中。源代码可能仍然是开放的,但贡献的大门正在关闭。
或许这是一个完全合理的权衡。但这确实是一种权衡。而我们似乎对基准测试的这一面并不特别感兴趣。
## 闪亮的未必都是黄金
有时它只是生锈了。
软件工程一直饱受一种特别严重的"闪亮物体综合症"。语言有自己的高光时刻。框架变得时尚。几个成功的项目确立一种模式,公司投入其中,会议演讲接踵而至,笔记本电脑贴纸四处分发,突然之间,一个技术决策就成了主要卖点。
"用Rust编写"开始听起来不像是实现细节,而更像是一个功能特性。
成功滋生模仿。一个工具被重写后速度显著提升。另一个紧随其后,再一个接一个。同行压力不断增加。很快,用JavaScript编写开始看起来不像是JavaScript工具链的明智选择,更像是一个必输的赌注。
> 我们正在为一个喜欢悠哉游哉的蒸汽火车铺设越来越快的轨道。
这一切并不意味着那些编译型语言不是完成这项工作的正确工具。通常,它们恰恰就是正确的选择。但是,*适合这项工作的工具*与*适合所有与竞争对手所做之事表面相似的工作的工具*之间是有区别的。
一旦闪亮的新工具碰巧又在基准测试中名列前茅,抵制它就变得难上加难。速度提供了技术论据。流行度则包办了其余一切。
## 目的地未知
我们对更快JavaScript的追求,将我们带到了一个颇为奇特的地方。
我们正在用Rust编译JavaScript,以产出在主要用C++编写的引擎中运行的JavaScript。
或许这是成熟生态系统自然演进的过程,而JavaScript无需吞噬整个技术栈就能保持其相关性。语言可以共存并各自繁荣。网络正是建立在至少三种语言之上的,后来又加入了更多。
单独看,每一步都完全合乎逻辑。但合在一起看,它们指向了一个更有趣的远方。我们投入了大量工程资源来优化JavaScript周围的一切,而JavaScript本身仍是最终目的。我们正在为一个喜欢悠哉游哉的蒸汽火车铺设越来越快的轨道。
速度的问题在于,当火车本身并非为追赶而设计时,它并不能保证旅途的平稳。迟早,更快的轨道带来的收益会越来越小。而某个比我聪明得多的人将不得不提出这个尖锐的问题:在彻底重建网络开始看起来是更理智的选择之前,我们还能走多远?
相似文章
JavaScript的诞生与消亡(2014)
Gary Bernhardt在PyCon 2014上的一场演讲,幽默地追溯了JavaScript从1995年到2035年的历史与未来,讨论了其缺陷与积极影响。
Web 承受不起 JavaScript 运行时的单一化格局
这篇文章探讨了 Deno 团队加入 Cloudflare、Deno 将停止开发后 JavaScript 运行时整合所带来的风险,并警告称,独立运行时数量的减少可能会使 Web 创新停滞,重演 IE6 和 Chromium 单一生态时代的局面。
为什么选择原生JavaScript
一篇讨论不使用库或框架的原生JavaScript的优点和用例的文章。
不久我们就能终于将 JavaScript 放逐至 ShadowRealm
本文探讨了 TC39 提出的 ShadowRealm 提案,该提案旨在允许在不使用 iframe 或 Web Workers 的情况下,在隔离环境(Realm)中执行 JavaScript,从而改善代码沙盒机制并提升性能。
我希望 Deno 能继续做它最擅长的事
一篇反思性文章,批评 Deno 转向与 Node.js 兼容的做法,认为这削弱了其原本简洁、零配置的理念,而正是这些特点让开发者对其青睐有加。