gol*_*422 26 javascript commonjs es6-modules
当前的 Javascript 采用importES6 作为导入模块的标准方式。但是,我有时会看到使用 CommonJSrequire而不是import.
我首先想知道两个是否可以一起使用,但似乎两个不能互换。(相关的stackoverflow问题)
那么,CommonJS“需要”的东西还在项目中使用吗?或者它正在慢慢消亡并且仅需要维护遗留代码?
jfr*_*d00 38
CommonJS 可能会在 Nodejs 中长期得到支持,因为仍有数百万行代码使用它编写。 它是nodejs中原始的模块加载机制。 它没有被弃用。
\nESM 模块(ECMAScript 模块)使用的import是export模块的新 Javascript 标准,我们可以预期,只要它们是 Javascript 标准(可能永远),nodejs 就会支持它们。
这两个模块标准并不完全兼容,因此在同一项目中混合和匹配可能会导致复杂化,您必须学习如何处理。
\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 模块:
\nimport { 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或__filename准确地告诉您该文件是从哪里加载的。相反,您必须解析这些值import.meta.url并计算它们。所以,仍然可以获得这些信息,只是不像以前那么方便了。
另一方面,ESM 模块具有awaitCommonJS 所没有的一些功能(例如顶级功能),这可能非常有用。
您的具体问题
\n\n\n那么,CommonJS“require”还在项目中使用吗?
\n
是的,它仍然被大量使用。
\n\n\n或者它正在慢慢消亡并且仅需要维护遗留代码?
\n
[截至 2022 年初的评论] 我不会说它正在消亡,因为 NPM 上很少有项目仍然支持 CommonJS。事实上,当一个项目发布不再支持 CommonJS 的新版本时,它会给他们的用户群带来相当大的问题(我们在 stackoverflow 上看到其中一些问题),因为 CommonJS 项目仍然非常流行,而且人们不熟悉 CommonJS如何加载不同的模块类型。
\n因此,我想说,我们仍处于从 CommonJS 到 ESM 过渡的早期阶段,而且更像是 ESM 正在得到越来越多的采用,而不是 CommonJS 正在消亡。我大胆猜测,NPM 上的大多数模块将在未来几年内转向支持从两种模块格式直接加载。
\n转译
\n最后,开发人员经常使用转译来允许他们使用最新的语法和功能编写代码,但使用转译器将代码转换回可以在任何地方运行的较低的公分母。这也可以用于模块架构(在 ESM 中编写代码,转换为 CommonJS)。
\n一些有趣的参考资料
\n\n\nNode 模块的战争:为什么 CommonJS 和 ES 模块不能相处
\n在 Node.js 中从 CommonJS 迁移到 ECMAScript 模块 (ESM) 所需了解的一切
\n