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

gol*_*422 26 javascript commonjs es6-modules

当前的 Javascript 采用importES6 作为导入模块的标准方式。但是,我有时会看到使用 CommonJSrequire而不是import.

我首先想知道两个是否可以一起使用,但似乎两个不能互换。(相关的stackoverflow问题

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

jfr*_*d00 38

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

\n

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

\n

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

\n

新项目

\n

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

\n

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

\n

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

\n

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

\n

现有的 CommonJS 项目

\n

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

\n

互操作性

\n

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

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

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

\n

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

\n

另一方面,ESM 模块具有awaitCommonJS 所没有的一些功能(例如顶级功能),这可能非常有用。

\n

您的具体问题

\n
\n

那么,CommonJS“require”还在项目中使用吗?

\n
\n

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

\n
\n

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

\n
\n

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

\n

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

\n

转译

\n

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

\n

一些有趣的参考资料

\n

支持 Node.js ESM 需要什么?

\n

混合 npm 包(ESM 和 CommonJS)

\n

Node 模块的战争:为什么 CommonJS 和 ES 模块不能相处

\n

在 Node.js 中从 CommonJS 迁移到 ECMAScript 模块 (ESM) 所需了解的一切

\n

  • @Bergi - 再次更新。我还更新了答案的语气,因为确实不再有任何理由不在新项目中使用 ESM 模块,因为加载 CommonJS 模块的向后兼容性现在比一年前要好得多。 (5认同)