且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

es6模块如何导入?

更新时间:2022-10-19 14:22:16

循环依赖对于声明性导入/导出没有问题。在你的情况下,圆圈的最小长度是: - )



解决方案是, import 将值导入到变量中,但是它将一个变量引用导出到导出的变量中。有关可变变量的示例,请查看此处,并在这个问题用于确切的术语。

它对于模块命名空间对象是一样的 - 它们的属性只是解析为实际导出变量的getter。 >

所以当你的模块被加载和评估时,会出现以下步骤:


  1. 静态分析 export import 声明以构建依赖图

  2. 模块范围已创建

  3. 由于模块唯一的依赖关系本身就已经被初始化了,所以不必等待

  4. fooModule 变量被创建并实例化为具有模块导出名称的对象,该模块已知为 [logFoo] fooModule.logFoo 属性成为一个getter,它将评估模块范围中的 logFoo 变量(如果您已经使用 export {A as B} ,然后 fooModule.B 将解析为 A ,但在你的情况下,这两个名字是一样的)。

  5. 模块范围中的变量声明创建变量,在你的情况下 logFoo ,并且函数声明被初始化(即 logFoo 获得分配的功能)

  6. 模块代码运行你的情况下没有任何反应)

现在当你在一个模块中调用 logFoo 导入它, fooModule 将引用包含 logFoo 的命名空间。没有魔法: - )


I have a module called fooModule. Inside this module, I import fooModule (itself):

import * as fooModule from './fooModule';

export function logFoo() {
  console.log(fooModule)
}

When logFoo() is called, I can see all of the exports of the fooModule. How does this work?

Circular dependencies are no problem for declarative imports/exports. In your case, the circle is of minimal length though :-)

The solution is that an import does not import a value into a variable, but that it makes a variable a reference to the exported variable. Have a look here for an example of a mutable variable, and at this question for exact terminology.
And it's the same for module namespace objects - their properties are just getters that resolve to the actual exported variable.

So when your module is loaded and evaluated, the following steps occur:

  1. The source is statically analysed for export and import declarations to build a dependency graph
  2. The module scope is created
  3. Since the only dependency of your module is itself, and that already is getting initialised, it doesn't need to wait for it
  4. The fooModule variable is created and instantiated to an object with the exported names of the module, which are known to be ["logFoo"]. The fooModule.logFoo property becomes a getter that will evaluate to the logFoo variable in the module scope (if you had used export {A as B}, then fooModule.B would resolve to A, but in your case both names are the same).
  5. The variable declarations in the module scope create the variables, in your case logFoo, and function declarations are initialised (i.e. logFoo gets assigned the function)
  6. The module code is run (in your case, nothing happens)

Now when you call logFoo in a module that imports it, fooModule will refer to the namespace that contains logFoo. No magic :-)