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 模块:
- 使用静态导入:
import { callMeCommon } from '../otherProject/common.js';
- 通过动态导入
import(someFile).then(...)
- 通过使用
module.createRequire(import.meta.url)
然后用它require()
加载 CommonJS 模块的函数。
您还可以使用动态import('someModule').then(...)
从 CommonJS 模块加载 ESM 模块,但它不是同步的require()
所以必须以不同的方式处理。
了解 ESM 模块没有 CommonJS 模块所具有的一些 Nodejs 细节也很有用。没有自动的__dirname
or __filename
准确地告诉您该文件是从哪里加载的。相反,您必须解析这些值import.meta.url
并计算它们。所以,仍然可以获得这些信息,只是不像以前那么方便了。
另一方面,ESM 模块具有一些功能,例如顶级await
CommonJS 不具备的功能非常有用。
您的具体问题
那么,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/