likes
comments
collection
share

JavaScript 运行时环境和标准

作者站长头像
站长
· 阅读数 23

根据 SlashData 2021 年发布的开发者调研分析,JavaScript 在全球拥有最多的开发者数量,成为世界上最流行的编程语言。

本文发布更新于 2022年11月,部分信息需注意时效性。

JavaScript 主要运行在浏览器端,随着技术不断发展,出现很多服务端的 JavaScript 运行时,甚至可以做硬件相关的嵌入式开发。

开发时,前后端同构使用同一种编程语言,对 JavaScript 开发者的体验相当友好。

但不同端的 JavaScript 运行时,会有一些差异。

Web 标准规范组织

JavaScript 标准规范是由 ECMA International 组织制定,但很多 Web APIs 不属于 ECMAScript 规范标准。

这些 Web APIs 规范标准是由 WHATWGW3C 来制定的,包括 HTML、DOM、调试用的 Console API、编码相关的 Encoding、请求相关的 Fetch API、存储相关的 Storage 等等,都有相关的规范标准。

浏览器端几乎会实现大部分的 Web APIs 规范标准,服务器端则会选择性的遵循部分 Web APIs 标准规范,而一些则是服务端特有的,比如 Node.js 的 Common JS 模块规范等。

JavaScript 运行时(JS Runtime)

JavaScript 运行时就是 JS 代码的执行环境,一般包括有 JS 引擎、Web APIs、事件循环机制(Event Loop、JS 单线程异步执行机制)、内存管理、堆栈管理等等,一切如何将 JS 代码正确执行的都属于 JavaScript 运行时。

JS 引擎比较有名的是 Chrome 的 V8、Firefox 的 SpiderMonkey、Safari 的 JavaScriptCore,另外还有轻量化的 QuickJS、Hermes 等。

尽管都使用 JavaScript 语言,但到了服务端,JavaScript 就是一门后端语言,它没有 DOM、Window、Canvas、Cookies 等一些浏览器相关的 Web APIs,进而会有文件系统 API、网络相关 API、与底层操作系统交互的各种 API 等等。

Server-side JavaScript Runtime

服务端 JavaScript 运行时环境著名的有 Node.jsDeno,基于 V8 引擎,Deno 则使用 Rust 来原生支持了 TypeScript 。

发展较晚的 Bun 则采用 JavaScriptCore 引擎,并采用新兴的系统编程语言 Zig 编写。

Node.js 开创了让 JavaScript 可以写后端程序,Deno、Bun 则有了更好的性能。

JavaScript 作为后端语言,优势为异步非阻塞、事件驱动机制。同时支撑着庞大的前端工程化相关体系,包括很多的脚手架、打包工具、一些前端相关的编译器等等。

Rust、Zig 皆为系统级别的编程语言,对标 C/C++ 语言。Rust 专注于高性能、内存安全;Zig 主打稳定性、可维护性和高性能。

Edge-side JavaScript Runtime

基于 Server-side JavaScript 运行时,并提供适合边缘计算场景的一些 API。

CDN 作为内容存储分发,用户可以就近取得所需内容;边缘计算则提供计算能力,让服务端的能力在靠近用户的边缘节点上就可以提供。

依托覆盖全球的边缘节点,在提供存储的基础上提供一定的计算能力,边缘计算可以更好的提高应用性能和延迟。

JavaScript 运行时环境和标准

现有主流边缘计算相关的产品有:

  • AWS Lambda@Edge
  • Cloudflare Workers
  • Vercel Edge Functions
  • Netlify Edge Functions

他们都支持使用 JavaScript 来编写在边缘节点运行的后端代码(无需自己的服务器),Lambda@Edge、Cloudflare Workers、Vercel Edge Functions 基于 Node.js 来作为他们的 JavaScript 运行时,Netlify Edge Functions 则选择基于 Deno。

因为是边缘节点的 JavaScript 运行时,所以在使用一些 API 上会有所限制,比如不能使用本地文件系统、对代码大小的限制、执行时间限制等,并且会提供一些扩展的 APIs 来满足自己的相关业务需求。

普通的 CDN 中,你只能存取静态文件内容,没有命中则会从源站中取得然后缓存在节点中。边缘计算则可以将本来放在单个地区的服务器的一些业务逻辑放到靠近用户的边缘节点中,比如一些 A/B 测试、权限授权验证、缓存 API 内容、API 请求限制等等。

Bun 有着更好的启动速度和性能,更适合边缘计算场景的运行时,有了稳定版本后,之后许多厂商应该会跟进采用。

IoT-side JavaScript Runtime

一些嵌入式设备上也可以运行 JavaScript 并驱动设备,这需要在内存和计算资源都极其有限的情况下,优化 JavaScript 运行时,并针对硬件也有相关的优化。

大多会选择性的遵循 ECMAScript 部分标准和部分 Web APIs 规范标准,还会提供一些嵌入式特有的 API ,一切为了在有限资源的嵌入式设备上可以流畅运行。

相关的 JavaScript 运行时有:

Application JavaScript Runtime

许多应用也会利用 JavaScript 运行时来实现自己的需求。比如因为 Node.js 的特性,很多 NoSQL 都使用 Node.js 来查询数据和管理应用。

Nginx 则通过自研 JavaScript 运行时 njs 来扩展 Nginx 功能,参考 Nginx 中运行 JavaScript 详细介绍。

前端跨平台方案。小程序、React Native、Weex 等,都有自己的 JavaScript 运行时,iOS 上一般都基于 JavaScriptCore、Android 上则是 V8。因为使用在移动端,需要兼顾引擎的大小、性能、内存使用等,React Native 团队则自己研发了 JS 引擎 Hermes 。

WinterCG

WinterCG 社区(Web-interoperable Runtimes Community Group),是由 Cloudflare 、Node.js、Deno 合作最近正式成立的一个社区组。

致力于促进 Web APIs 标准的发展。让开发者可以在不同的 JavaScript 运行时中编写可移植的代码,包括浏览器端、服务端、嵌入式应用、边缘计算等,即 Write oncerun everywhere.

我把 Web APIs 分为三种:

  • 只适用于浏览器端,比如像 HTML、CSS、Canvas 的规范标准,可访问性相关的标准等。
  • 只适用于非浏览器端,比如像本地文件系统、和操作系统交互的 API 等。
  • 多端通用,比如 Encoding、Fetch、URL、Stream 等。

WinterCG 的定位是,与现有的 Web APIs 标准规范组织(如 WHATWG 、 W3C)合作,充分考虑浏览器端和非浏览器端 JavaScript 运行时所需要的异同 ,让标准可以通用化。

如果一些标准在浏览器端和非浏览器端需要有必要的差异,则提供描述这些差异的清晰文档。

不排除如果一些功能只适合于非浏览器端,并且与现在的 Web API 标准不冲突,则可能会发布自己的规范进行推进。比如只存在于服务端的文件系统等、未来发展的边缘计算 JavaScript 运行时中,必定会有新的运行时规范需要推进。

总结

WHATWG 和 W3C 在浏览器端的 Web APIs 标准规范已经很全。但随着不同类型的 JavaScript 运行时的发展,每种运行时的使用场景和解决的问题可能都会有所差异。

如果所有的 JavaScript 运行时都可以使用同一套标准规范,这必定有利于各 JavaScript 运行时的发展,各运行时可以直接使用现有的标准规范来实现,而非自己实现临时的方案。

开发者可以以最小的代价移植应用程序到不同平台,比如可以无缝的在不同的边缘计算服务的厂商中迁移,Node.js 和 Deno 的代码可以完全复用。

参考链接

转载自:https://juejin.cn/post/7165521745674240013
评论
请登录