文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

模块化规范 CommonJS 会消失吗?

2024-11-30 11:24

关注

当谈到 JavaScript 的模块化规范时,我们不可避免地会提到 CommonJS。多年来,CommonJS 在 Node.js 生态系统中扮演着至关重要的角色,它让开发者能够方便地使用模块化的代码组织方式。然而,随着 ES Modules(ESM)的出现和日益普及,人们开始思考一个问题:CommonJS 是否注定会消失?在本文中,我们将探讨 CommonJS 的现状和未来,并评估它与ESM之间的关系。是否真的可以全面过渡到ESM,抛弃CommonJS?让我们一起来看看。

CommonJS 的兴起

JavaScript 出现大约 15 年后,开始从浏览器扩展到服务端。许多更大的项目选择使用 JavaScript 进行构建,而 JavaScript 需要一种更好的方法来处理大量源代码,它需要模块化

2009 年,Mozilla 的开发者 Kevin Dangoor 发出了号召。在 “服务端 JavaScript 需要什么”一文中,他列举出了服务端 JavaScript 所缺少的许多内容,包括模块系统。

JavaScript 需要一种标准的方式来包含其他模块,并且这些模块应该存在于独立的命名空间中。虽然有一些简单的方法来创建命名空间,但是目前还没有一种标准的编程方式来加载一个模块(一次性)。这一点非常重要,因为服务端应用可能包含大量代码,并且可能会混合和匹配满足这些标准接口的部分。

— 出自Kevin Dangoor的《Server Side JavaScript需要什么》(2009年)

在一周内,包括 npm 的创始人 Issac Schlueter 和 Node.js 的创建者 Ryan Dahl 在内,共有 224 人加入了当时称为 ServerJS 的 Google 群组。该邮件列表将继续规范 CommonJS 的第一个版本,该模块系统成为 Node.js 的一部分。

提议的 CommonJS 语法(require()、module.exports等)看起来并不像客户端JavaScript。这是经过设计的。Dangoor意图将CommonJS与浏览器JavaScript区分开来,这一点从他 2009 年在 CommonJS Google 群组上的消息中就可以看出来:

我确实认为服务端代码的需求与客户端代码的需求有很大不同,因此最好从 Python 和 Ruby 中获取,而不是从 Dojo 和 jQuery 中获取。

除了 Node.js 之外,其他几个早期的服务端 JavaScript 运行时也采用了 CommonJS,例如 Flusspferd、GPSEE、Narwhal、Persevere、RingoJS、Sproutcore 和 v8cgi(大多数由核心 CommonJS 团队构建)。

但随着 Node.js 成为真正的服务端 JavaScript 运行时,并以 CommonJS 作为其主要模块系统,更广泛的 CommonJS 标准化工作失去了动力。当只有一个主要运行时时,对标准的需求就会减少:Node.js 实现就成为了标准。

尽管 CommonJS 是默认的模块系统,但它仍然存在一些核心问题:

到 2013 年,CommonJS 小组开始逐渐解体。但到了那一年,负责监督 JavaScript 核心语言更新的 TC39 委员会已经开始开发 CommonJS 模块的后继者:ECMAScript 模块。

ECMAScript 模块是面向Web的

随着ES6语言规范的发布,TC39委员会最终引入了一个直接嵌入到JavaScript语言中的模块系统。其目标是构建一个适用于Web的单一模块加载器系统,包括异步模块加载、与浏览器兼容、静态分析和 tree shaking。ES模块假设它们将从网络中获取数据,而不是从文件系统中获取,以提供更好的性能和用户体验。

现在,由于模块加载系统已经直接集成到语言中,大家都会使用它,这样就可以将精力集中在更高级别、更重要的问题上了。

Node 决定同时支持 CJS 和 ESM

Borins 是 Node“模块团队”的开发人员之一,负责在 Node.js 中实现 ES 模块。尽管成功地将 ESM 添加到 Node,但团队未能就 ESM 和 CJS 之间的互操作性达成明确的共识。然而 Node 无法摆脱 CJS,因为它的嵌入程度如此之深。这意味着互操作性问题被推给了软件包作者。

以下是支持 ESM 和 CJS 所需的模块 package.json 的片段:

显然,支持 CommonJS 已经成为不容忽视的问题。但是,CommonJS 真的是一无是处嘛?

CommonJS 的优势

CommonJS 启动速度更快

对于较大的应用,ES 模块速度较慢。与 require 不同,要么需要在使用语句时加载整个模块图,要么需要使用表达式等待每个导入。例如,如果想要延迟加载一个包以在函数中使用,代码必须返回一个 Promise。

async function transpileEsm(code) {
  const { transform } = await import("@babel/core");
  // ... return 必须是一个 Promise
}

function transpileCjs(code) {
  const { transform } = require("@babel/core");
  // ... return 是同步的
}

ES模块为了绑定导入和导出,需要进行两次处理。整个模块图会被解析和分析,然后代码会被评估。这些被分为不同的步骤。正是这种方式使得ES模块中的“实时绑定”成为可能。

考虑以下两个简单的文件:

// babel.cjs
require("@babel/core")

// babel.mjs
import "@babel/core";

Babel 是一个由大量文件组成的包,因此比较这两个文件的运行时间是评估与模块解析相关的性能成本的好方法。结果如下:

在 Bun 中(一个新的 JavaScript 运行时),使用 CommonJS 加载 Babel 的速度大约比使用 ES 模块快 2.4 倍,相差了 85ms。在无服务器冷启动的情况下,这个差距是巨大的。在 Node.js 中,差异为 1.8 倍(约 60 毫秒)。

增量加载

CommonJS 允许动态模块加载——可以有条件地 require() 文件,或者 require() 动态构造的路径/说明符,或者在函数体中 require()。这种灵活性在需要动态加载的场景中非常有利,例如插件系统或基于用户交互的延迟加载特定组件。

ES 模块提供了具有类似属性的动态 import() 函数。从某种意义上说,它的存在证明了 CommonJS 的动态方法具有实用性并受到开发人员的重视。

现状

发布到 npm 的数百万个模块已经使用 CommonJS,其中许多都是:

(a) 不再积极维护。

(b) 对现有项目很重要。

可能永远不会达到所有包都可以使用 ES 模块的地步。不支持CommonJS的运行时或框架将失去巨大的价值。

小结

尽管 ES Modules(ESM)的出现给予了 CommonJS 微弱的竞争压力,但我们可以得出结论:CommonJS 不会轻易消失。

CommonJS 在 Node.js 生态系统中的广泛应用以及大量已发布在 npm 上的模块都使用了 CommonJS 规范,这使得 CommonJS 成为不可忽视的存在。很多模块虽然不再得到积极维护,但对于现有项目仍具有重要性。因此,在实际应用中,对于不支持 CommonJS 的运行时或框架来说,忽视 CommonJS 将意味着错失巨大的价值。

尽管 ES Modules 在语言层面提供了更强大的静态分析和优化能力,并且被认为是 JavaScript 的未来,但 CommonJS 仍然具有优势。它简单易用,适合动态加载和代码重用。因此,在目前的情况下,我们仍然需要将 CommonJS 视为一个重要的模块化规范。

无论是 CommonJS 还是 ES Modules,它们都有各自的特点和适用场景。我们不应该试图完全取代 CommonJS,而是应该在技术发展的过程中平衡实用性和未来趋势。只有这样,才能更好地利用 JavaScript 的模块化能力,为项目和生态系统带来最大的价值。

参考资料:

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯