NodeJS 中的导入导出调用顺序

Import-Export Call Order in NodeJS

这是一道“代码论”题。

所以想象一下这个场景,我在一个包中使用全局命名空间。我有一个主入口点文件,一些我导出的 class 文件,以及一些 classes 使用的实用程序文件。这是理论上的文件结构:

/index.js (main entrypoint)  
/src  
|_/source.js (exporting function for src folder)  
|_/utils  
  |_/headers.js
  |_/constants.js
|_/classes
  |_/class1.js
  |_/class2.js

在constants.js中我定义了一些全局变量,然后导出了一个使用了一些全局变量的对象。
/src/utils/constants.js

const foobar = 'foo';
global.foobar = foobar;

export default {
  foo: global.foobar,
}

在一些 class 文件中我导入 constants.js.
/src/classes/class1.js

import constants from '../utils/constants.js'

export default class Xyzzy {
  function baz() {
    return constants.foo + 'baz'
  }
}

最后在入口点文件中导入 source.js 导入 /src/classes/class1/src/classes/class2 并导出它们,然后定义一些全局变量。
/index.js

import source from '/src/source.js'

export default function index() {
  global.foobar = 'bar'
  
  return {
    class1: source.class1,
    class2: source.class2,
  }
}

global.foobar的赋值顺序是什么,最后的结果是什么,最重要的是为什么会这样

谢谢!

import 声明类似于 require-oncelazy-require。模块一旦被导入就会被评估:进一步的导入不会再次评估它。

因此,关于 foobar 如何变异,根据您的导入,应该按顺序发生以下情况:

    1. src/utils/constants.jsglobal.foobar = 'foo'
    1. index.jsglobal.foobar = 'bar'

入口代码什么都不做,它只导出一个函数作为 属性 default.

来自https://hacks.mozilla.org/2015/08/es6-in-depth-modules/

When you run a module containing an import declaration, the modules it imports are loaded first, then each module body is executed in a depth-first traversal of the dependency graph, avoiding cycles by skipping anything already executed.

所以在你的情况下:

  1. 加载入口点模块index.js,依赖source.js
  2. 加载source.js模块,依赖class1.jsclass2.js
  3. 加载class1.js模块,依赖constants.js
  4. constants.js 模块已加载,不依赖任何东西,因此被评估。这会将 'foo' 分配给 foobar 变量。
  5. 至此class1.js的依赖已经满足,执行
  6. (假设 class2.js 看起来类似于 class1.js),class2.js 模块已加载,并依赖于 constants.js。这已经初始化,所以 class2.js 被执行。
  7. 至此source.js的依赖已经满足,执行
  8. 既然满足了index.js的依赖,就执行了。这会将 'bar' 分配给 foobar 变量。

当然,模块的全部目的是当你不使用全局变量时,你应该需要对此进行推理:-)