CommonJS 'require' 是否仍在使用或已弃用?

2024-02-14

目前Javascript采用importES6 作为导入模块的标准方式。 但是,我有时会看到使用 CommonJS 的代码require代替import.

我首先想知道两个是否可以一起使用,但似乎两个不能互换。 (相关堆栈溢出问题 https://stackoverflow.com/questions/55167994/is-it-possible-to-es6-import-a-commonjs-module)

那么,CommonJS“需要”的东西还在项目中使用吗?或者它正在慢慢消亡并且仅需要维护遗留代码?


CommonJS 可能会在很长一段时间内在 Nodejs 中得到支持,因为仍有数百万行代码使用它编写。它是nodejs中原始的模块加载机制。 它没有被弃用.

使用的 ESM 模块(ECMAScript 模块)import and export是模块的新 Javascript 标准,我们可以预期,只要它们是 Javascript 标准(可能永远),nodejs 就会支持它们。

这两个模块标准并不完全兼容,因此在同一项目中混合和匹配可能会导致复杂化,您必须学习如何处理。

新项目

如果我今天开始一个新项目,我会选择使用 ESM 模块编写代码,因为这是该语言和 Nodejs 的未来轨迹。而且,如果您需要与其他模块向后兼容,您仍然可以将 CommonJS 模块加载到 ESM 模块中,但您必须知道如何正确执行 - 混合和匹配模块类型并不总是无缝的。

当 Nodejs 首次支持 ESM 模块时,与 CommonJS 模块的互操作性功能不是很完整,并且造成了一些困难。从 Nodejs 的最新版本开始,您可以从 ESM 模块加载 CommonJS 模块,反之亦然 - 您只需使用正确的技术即可做到这一点。这使得现在在 ESM 项目中工作比 NodeJS 中的 ESM 支持首次出现时更加可行,因为您仍然可以访问 NPM 中仅支持 CommonJS 的库。

另请注意,NPM 中越来越多的库支持从任一模块类型直接加载,因此无论您的项目是 CommonJS 还是 ESM,它们都同样易于使用。

随着时间的推移,我预计 NPM 上任何积极开发的共享模块最终都将支持作为 ESM 模块直接加载。但是,我们正处于这个过渡时期,许多人尚未实施该方案,或者在实施新的加载方案(它有自己的不同规则集)方面存在特殊的挑战。同时,您仍然可以将 CommonJS 模块加载到 ESM 项目中。

现有的 CommonJS 项目

如果我有一个现有的 CommonJS 项目,我不会花任何时间考虑将其转换为 ESM,因为 CommonJS 仍然得到广泛支持,而且我的开发人员时间可能更好地花在添加功能、测试、修复错误等上。 ..比转换模块格式。

互操作性

需要了解的重要的互操作性事情之一是,您可以通过多种不同的方式从 ESM 模块加载 CommonJS 模块:

  1. 使用静态导入:import { callMeCommon } from '../otherProject/common.js';
  2. 通过动态导入import(someFile).then(...)
  3. 通过使用module.createRequire(import.meta.url)然后用它require()加载 CommonJS 模块的函数。

您还可以使用动态import('someModule').then(...)从 CommonJS 模块加载 ESM 模块,但它不是同步的require()所以必须以不同的方式处理。

了解 ESM 模块没有 CommonJS 模块所具有的一些 Nodejs 细节也很有用。没有自动的__dirname or __filename准确地告诉您该文件是从哪里加载的。相反,您必须解析这些值import.meta.url并计算它们。所以,仍然可以获得这些信息,只是不像以前那么方便了。

另一方面,ESM 模块具有一些功能,例如顶级awaitCommonJS 不具备的功能非常有用。

您的具体问题

那么,CommonJS“需要”的东西还在项目中使用吗?

是的,它仍然被大量使用。

或者它正在慢慢消亡并且仅需要维护遗留代码?

[截至 2022 年初的评论] 我不会说它正在消亡,因为 NPM 上很少有项目仍然支持 CommonJS。事实上,当一个项目发布不再支持 CommonJS 的新版本时,它会给他们的用户群带来很大的问题(我们在 stackoverflow 上看到其中一些问题),因为 CommonJS 项目仍然非常流行,而且人们不熟悉 CommonJS如何加载不同的模块类型。

所以,我想说,我们仍处于从 CommonJS 到 ESM 过渡的早期阶段,更像是 ESM 正在得到越来越多的采用,而不是 CommonJS 正在消亡。我大胆猜测,NPM 上的大多数模块将在未来几年内转向支持从两种模块格式直接加载。

转译

最后,开发人员经常使用转译来允许他们使用最新的语法和功能编写代码,但使用转译器将代码转换回可以在任何地方运行的较低的公分母。这也可以用于模块架构(在 ESM 中编写代码,转换为 CommonJS)。

一些有趣的参考资料

支持 Node.js ESM 需要什么? https://www.the-guild.dev/blog/support-nodejs-esm

混合 npm 包(ESM 和 CommonJS) https://2ality.com/2019/10/hybrid-npm-packages.html

Node 模块的战争:为什么 CommonJS 和 ES 模块不能相处 https://redfin.engineering/node-modules-at-war-why-commonjs-and-es-modules-cant-get-along-9617135eeca1

在 Node.js 中从 CommonJS 迁移到 ECMAScript 模块 (ESM) 所需了解的一切 https://pawelgrzybek.com/all-you-need-to-know-to-move-from-commonjs-to-ecmascript-modules-esm-in-node-js/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CommonJS 'require' 是否仍在使用或已弃用? 的相关文章

随机推荐