【问题标题】:CommonJS vs ES Modules [closed]CommonJS 与 ES 模块 [关闭]
【发布时间】:2020-10-06 19:19:37
【问题描述】:

有人能解释一下为什么 CommonJS 是动态的,而 ES 是静态的吗?在这种情况下,动态和静态意味着什么?而且我对解析时间和运行时间之间的区别感到很困惑,希望有人也能解释一下。谢谢!

【问题讨论】:

  • “静态”指的是static analysis,用于在不执行代码的情况下确定模块具有哪些依赖项。

标签: javascript commonjs es6-modules


【解决方案1】:

说“解析时间”有点迂腐,因为这是指运行应用程序之前的时间,通常称为编译时间。模块允许在运行之前检查和映射与每个模块的文件位置、导入和导出相关的一些代码 - 在“解析时间”。在运行单个函数之前,会解析每个函数,这意味着它的名称和其他属性被组装,以便其他模块可以导入它们。此时函数调用的结果和变量的值是未知的,但函数本身是已知的。

使用 ES 导入时,导入的变量、函数等不是通常动态组装的(有一个部分实现的提案记录在 here),这发生在运行时。使用 ES 程序显式声明依赖关系,而不管任何程序差异。以不同的顺序导入并不重要。无论导入的代码是否健全,结果都是相同的——即静态的,并且在任何代码被评估为任何值之前,导入语句是正确还是不正确。

因为 CommonJS 一次计算的代码比 ES 多,所以如果以顺序方式执行,就会知道更多。其中一个含义是 require 语句的字符串中的代码可以有变量,使语句动态,但 ES 不能。 ES 导出被解析,但在评估 import 语句时,整个模块对导入它的其他模块不可用。

有一个MDN article 更彻底地解释了这一点。

【讨论】:

  • "以不同的顺序导入无关紧要。" - 这并不完全正确。初始化顺序很重要。
  • @Bergi,您是说文件的初始化顺序还是文件中导入的初始化顺序或两者兼而有之?
  • 两者。代码的执行顺序很重要,这意味着 import 语句的顺序也很重要,因为前者取决于后者。
  • @Bergi 你能举一个例子,说明 ES 模块导入语句的顺序很重要吗?我知道循环依赖会破坏正常的 ES 模块导入。你有别的想法吗?
  • 循环依赖是一回事,但一般来说,如果模块代码执行有副作用,您可能会关心多个模块的执行顺序。无论如何,它与 commonjs 并没有什么不同(TDZ 除外)。
猜你喜欢
  • 1970-01-01
  • 2021-11-20
  • 2020-09-13
  • 2016-05-05
  • 2021-11-05
  • 2022-12-14
  • 2021-12-02
  • 2021-04-07
  • 2011-11-26
相关资源
最近更新 更多