脚本之家 设为“星标⭐”
第一时间收到文章更新
相比其他语言,我觉得 JavaScript
的生态系统太奇怪了,实际运行的代码已经不再是开发者编写的 JavaScript
,而是各种编译工具最终生成的产物。
这个问题有一定的历史原因,也是因为 JavaScript
社区对各种 “滥用” JavaScript
的包容性造成的,新的 React Server Components
进一步推动了这种情况,下面轻听我细细道来。
10
年前,JavaScript
还是非常糟糕的。它没有 Import
、Class
、async
、箭头函数、模板字面量、解构赋值、默认参数等能力。而且它主要运行的环境只有浏览器的 DOM
。JQuery
的出现让它变得稍微好了一些,但仍然很弱,但在那个时候,相对来说也还算是合理的。
将 JS
打包在浏览器中运行是它开始奇怪的第一个迹象。在这个过程中,我们还要同时缩减和压缩源代码,甚至可能还要进行代码拆分。一般来说,这个过程会同时读取多个 JavaScript
源代码作为输入,然后生成一个或多个 JavaScript
文件作为输出。这就意味着我们执行的代码并不是我们自己编写的代码,还需要借助 Sourcemap
才能还原。
然后,CoffeeScript
出现了。我们可以使用一种可以编译成 JavaScript
的语言来编写代码,而不是直接编写 JavaScript
。这和 Elixir、Kotlin
这样的语言不太一样,后者会编译成与另一种语言相同的字节码,而 CoffeeScript
实际上是编译成另一种语言。C++
最初也是这样开始的。
然后在 2015
年出现了 ECMAScript 6
,JavaScript
在接下来的几年里迅速改进,这也促使 CoffeeScript
被淘汰了,但又产生了一些新的问题:短时间内,浏览器的兼容性跟不上,所以像 Babel
这样的转译器应运而生,将当前和未来版本的 JavaScript
编译成可以在支持的环境中运行的较旧版本的 JavaScript
。当前,esbuild
作为新一代 JavaScript
打包器/转译器正在迅速崛起。
一路走来,emscripten
又出现了,它使用了 LLVM
编译器框架来将 C/C++
代码转换成中间代码,然后使用 Emscripten
工具链将中间代码转换成 JavaScript
代码。简单来讲,它将实际的机器代码编译成 JavaScript
的一个子集,尽管现在这个工具的新目标通常是 Wasm
。
最近,JavaScript
生态的创新速度似乎放缓了,JavaScript
的实现也做得越来越好,所以我们会认为对于在服务器端没有打包器的情况来说,转译器的需求会逐渐减少。但实际情况并非如此,原因是一个有趣的故事。
上面这个标题显然是有点夸张了,但是现在确实开始有这个趋势了。
如果你在编写 Rails
应用程序,则可以使用 Ruby
编写。如果你在编写 Django
应用程序,则可以使用 Python
编写。Phoenix,Elixir,Lavavel
,则使用 PHP
。Rails
因为使用了元编程进行了很多魔幻操作而受到了很多批评,而 Elixir
具有宏,但是所有上述的内容都是在语言可以完成的范围内的。
但是,JavaScript
就不一样了。虽然它的标准实际上由 EMCA TC39
标准化制定,但如果你使用的是像 Next.JS、Remix
或 Svelte
这样的流行框架,你的编码标准可能就不是 ECMA TC39
标准化的 ECMAScript
了。下面是一些例子:
ECMA
委员会标准化了 E4X
,使 XML
能够被视为一种数据类型。随后,它又失去了支持,被弃用并存档。多年后,Facebook
有了类似的需求,然后发明了 JSX
。它与 E4X
的不同之处在于,它会编译成 JS
。ECMA TC39
没有成功的标准化过类型注释,但是微软使用 TypeScript
实现了,它也会最终编译成 JS
。Svelte
有自己的编译器,甚至故意误用 JavaScript
标签语法来把语句标记为响应式。import
语句时,它们不一定认为被导入的文件是 JavaScript
,甚至不是上述任何变体之一。如果配置正确并且您想导入 CSS
或 PNG
文件,它会很乐意为你完成。我之前提到过 Rails
因为使用元编程而受到很多批评。但是大多数人对上述 JavaScript
语言的任何 “滥用” 都视而不见。JavaScript
生态系统就像是一个大帐篷派对。
最新打包器的滥用是 React Server Components(RSC)
。这种方式首先在 express
上演示过了,现在又被 Next.js
采用了。
“use server”
和 “use client”
除了是一段有效的 JavaScript
语句,其他的啥也不做,它们改变了接下来代码的含义。这个行为现在褒贬不一,但是在我看来,这非常符合 “use strict”
的精神,后者也改变了接下来代码的含义。
虽然 JSX
通常会编译成 JS
,但 Server React DOM API
支持编译成 HTML
。RSC
采用了不同的方式,并编译成了标记的 JSON
流。这对我们来说都是非常透明的,但它确实启用了一种不同的编程风格。许多人将其与 PHP
甚至 Rails
进行比较:
我不确定这些比较是不是意味着更积极的方式,但我会说从我的角度来看,这是一件非常好的事情。
从 fly.io
的角度来看,RSC
实现的更新(重新获取)序列是非常有趣的。我们一直特别青睐那些受地理分布影响的框架,例如 Elixir
的 LiveView
、Laravel
的 Livewire
和 Ruby on Rail
的 Hotwire
。我们希望这些框架能够成功,因为它们越成功,我们就越有价值。现在我们可以将 React
的 RSC
添加到这个列表中了。
回到手头上的话题,令人印象深刻的是,这样的功能只有通过与打包器的合作才能实现,这相当于对 JavaScript
语言本身进行了更改,意义深远,而且我敢说,也是令人愉快。
Dan Abramov
在 RemixConf
上发表了题为 React from Another Dimension
的演讲:
在 Dan
的演讲中,他想象了一个替代宇宙,其中 React
于 90
年代末首次在服务器上实现,并且仍然设法收敛到今天的状态。在演讲期间,他启动了一个 Windows 95
模拟器并使用 React
运行 Internet Explorer
(特别是 IE6
)。他甚至设法在使用该操作系统和浏览器组合的情况下完成了十个步骤中的九个。
但是这个演讲中令人费解的部分是他首先利用 use server
来实现客户端表单操作,然后才使用 use client
.
他最后说,这需要新一代路由器和新一代打包器。
想想所有这一切之所以成为可能,是因为我们编写的 JavaScript
不仅不是我们运行的 JavaScript
,而且在仔细检查下甚至根本不是 JavaScript
。
对此你怎么看?
<END> 程序员专属T恤
商品直购链接 👇
推荐阅读:
文章引用微信公众号"脚本之家",如有侵权,请联系管理员删除!