汇集三大 JavaScript 运行环境的 WinterCG 社区成立

战场小包 行业动态 1月前 阅读 1119

Cloudflare 与 Vercel、Shopify 将与 Node.js 和 Deno 的个人核心贡献者合作,共同成立一个新的社区小组,命名为 WinterCG,该小组汇集了三个最大的 JavaScript 环境,为开发人员提供了灵活性和选择,同时创建边缘计算的未来标准。

W3C 和 Web 超文本应用程序技术工作组 (WHATWG) 长期以来一直致力于为 Web 开发环境的 开发标准化 API 和功能。例如 fetch()ReadableStreamWritableStreamURLURLPatternTextEncoder 等现代 Web 开发中无处不在的 API 组件。然而,现有的章程一直只考虑 Web 浏览器的特定需求,导致开发的标准并不会针对 Web 浏览器进行优化。

像 Cloudflare Workers 这样的无服务器环境,或者像 Node.js 和 Deno 这样的运行时,都有诸多广泛的问题与不同的需求,这些都与 Web 浏览器无关,反之亦然。最终,在开发各种规范时,这些差异性需求的脱节和缺失,就导致了一种情况——非浏览器运行时已经实现了它们自己定制的、临时的解决方案,并且已经运行在了各个生产环境中。

WinterCG 社区的成立就是为了改变上述状况,它提供了一个用来讨论和倡导所有 Web 环境的共同需求的场所,可以部署在堆栈的任何地方。

对开发人员的好处

开发人员希望他们的代码具有良好的移植性,当写完一套代码后,如果需要迁移到不同的环境(例如从 Node.js 迁移到 Deno),你应该也不想重写一遍代码吧?

Cloudflare 用户会经常使用 npm 的一些模块,这些模块有的依赖于 Node.js 的 API,有的依赖于 Deno 的 API。如果希望利用这些 API ,通常需要引入 polyfill 来兼容实现。

Cloudflare Workers、Node.js、Deno 和 Web 浏览器虽然有很大的不同,但它们共享了很多共同的功能。例如,它们都提供了用于生成加密哈希的 API;它们都以某种方式处理流数据;它们都提供了向某处发送 HTTP 请求的能力。如果存在重叠,并且需求和功能是相同的,那么环境都应该实现相同的标准化机制。

Web 互操作性运行时社区小组

Web 互操作性是指在以在 Web 浏览器中实现功能的方式完全相同或至少尽可能一致的方式实现功能。例如 new URL() 在浏览器中的调用方式应该与 Node.js、Deno 和 Cloudflare Workers 中的 new URL() 调用方式完全一样。

然而,你必须承认一个事实,Node.js、Deno 和 Cloudflare Workers 明确不是 Web 浏览器,各种 JavaScript 运行环境的差异会极大影响标准化 API 的设计。例如 Node.js 和 Deno 都可以完全访问本地文件系统;Cloudflare Workers 则没有本地文件系统,而 Web 浏览器会限制对本地文件系统的访问。同样,虽然 Web 浏览器固有地包括一个网站 origin 的概念并实现 CORS 等机制来保护用户免受各种安全威胁,但在 Node.js, Deno 和 Cloudflare Workers 操作的服务器端却没有相同的 origin 概念。

到目前为止,W3C 和 WHATWG 都非常关注 Web 浏览器的需求。WinterCG 这一新的 Web 可互操作的运行时社区组将明确地处理并倡导每个人的需求。

但 WinterCG 也表示,他们并不准备发布一套独立的标准 API 集,只是将出现的新规范想法提交给 W3C 和 WHATWG 进行考虑,以获取和达到更多的共识。但是如果 Web 浏览器对其他环境所需的功能没有特别的需求,WinterCG 也可以自行推进规范,只要不引入与已建立的 Web 标准冲突或者不兼容的内容即可。

正在推进的工作

最小化通用 Web API

最小通用 Web API 是标准化 Web 平台 API 的一个精心设计的子集,旨在定义浏览器和非浏览器基于 JavaScript 的运行时环境的通用功能的最小集合。或者换一个说说,她是一组最小的通用 Web API ,将在 Node.js 、Deno 和 Cloudflare Workers 得到一致且正确地实现。大多数 API(除了一些例外和细微差别)已经存在于这些环境中,因此剩下的大部分工作是确保这些实现符合它们的相关规范并且可跨环境移植。

下面列出了该子集中的所有 API。WinterCG 表示,如果某个环境偏离 API 的标准化定义时 (比如 Node.js 对 setTimeout() 和 setInterval() 的实现),会提供描述这些差异的详细文档。而这种差异应该只存在于与现有代码的向后兼容性中。

Node.jsDenoCloudflare Workers
AbortController✔️✔️✔️
AbortSignal✔️✔️✔️
ByteLengthQueueingStrategy✔️✔️✔️
CompressionStream✔️✔️✔️
CountQueueingStrategy✔️✔️✔️
Crypto✔️✔️✔️
CryptoKey✔️✔️✔️
DecompressionStream✔️✔️✔️
DOMException✔️✔️✔️
Event✔️✔️✔️
EventTarget✔️✔️✔️
ReadableByteStreamController✔️✔️✔️
ReadableStream✔️✔️✔️
ReadableStreamBYOBReader✔️✔️✔️
ReadableStreamBYOBRequest✔️✔️✔️
ReadableStreamDefaultController✔️✔️✔️
ReadableStreamDefaultReader✔️✔️✔️
SubtleCrypto✔️✔️✔️
TextDecoder✔️✔️✔️
TextDecoderStream✔️✔️(很快)
TextEncoder✔️✔️✔️
TextEncoderStream✔️✔️
TransformStream✔️✔️✔️
TransformStreamDefaultController✔️✔️(很快)
URL✔️✔️✔️
URLPattern?✔️✔️
URLSearchParams✔️✔️✔️
WritableStream✔️✔️✔️
WritableStreamDefaultController✔️✔️✔️
globalThis.self?✔️(很快)
globalThis.atob()✔️✔️✔️
globalThis.btoa()✔️✔️✔️
globalThis.console✔️✔️✔️
globalThis.crypto✔️✔️✔️
globalThis.navigator.userAgent?✔️✔️
globalThis.queueMicrotask()✔️✔️✔️
globalThis.setTimeout() / globalthis.clearTimeout()✔️✔️✔️
globalThis.setInterval() / globalThis.clearInterval()✔️✔️✔️
globalThis.structuredClone()✔️✔️✔️
### Web Cryptography Streams

Web Cryptography API 为常见的密码学操作提供了少量且非常有限的 API,它的主要限制之一是与 Node.js 的内置 crypto 模块不同。Deno 是直接按 web crypto 规范实现的,而 Node 的内置 crypto 模块很早就开发完了,此次根据 Deno 和  Node.js 的现有实现制定规范,这为以后对其他平台的实现来说将更加方便与规范化。

为了解决这个问题,WinterCG 目前已经开始起草 Web Crypto Streams 的新规范,并提交给 W3C 进行考虑。

fetch()

Node.js 18.0.0 版本加入了 JavaScript 环境下的标准化 fetch API ,但是 Node.js、Deno 和 Cloudflare Workers 实现 fecth API 的方式与 Web 浏览器的实现方式有很多区别。

一方面,服务器环境下并没有 Web 浏览器下的 origin 概念,也没有防御跨域问题 CORS 等问题。同样,Web 浏览器通常一次被一个单独的用户使用,可以使用全局 cookie 进行存储,而服务器和无服务器应用程序被百万用户同时使用,全局 cookie 存储即不切实际又不安全。

由于环境的巨大差异,fetch 的实现标准很难达成共识,为了解决这个问题,WinterCG 正在编写获取 fetch 的一个子集,专门处理这些不同的需求和约束。最重要的是,这个子集将与 fetch 标准完全兼容,并且由在 Node.js、Deno 和 Cloudflare Workers 中从事 fetch 工作的同一批人合作开发。

评论