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-once 或 lazy-require。模块一旦被导入就会被评估:进一步的导入不会再次评估它。
因此,关于 foobar
如何变异,根据您的导入,应该按顺序发生以下情况:
-
src/utils/constants.js
集 global.foobar = 'foo'
-
index.js
集 global.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.
所以在你的情况下:
- 加载入口点模块index.js,依赖source.js
- 加载source.js模块,依赖class1.js和class2.js
- 加载class1.js模块,依赖constants.js
- constants.js 模块已加载,不依赖任何东西,因此被评估。这会将
'foo'
分配给 foobar
变量。
- 至此class1.js的依赖已经满足,执行
- (假设 class2.js 看起来类似于 class1.js),class2.js 模块已加载,并依赖于 constants.js。这已经初始化,所以 class2.js 被执行。
- 至此source.js的依赖已经满足,执行
- 既然满足了index.js的依赖,就执行了。这会将
'bar'
分配给 foobar
变量。
当然,模块的全部目的是当你不使用全局变量时,你应该需要对此进行推理:-)
这是一道“代码论”题。
所以想象一下这个场景,我在一个包中使用全局命名空间。我有一个主入口点文件,一些我导出的 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-once 或 lazy-require。模块一旦被导入就会被评估:进一步的导入不会再次评估它。
因此,关于 foobar
如何变异,根据您的导入,应该按顺序发生以下情况:
-
src/utils/constants.js
集global.foobar = 'foo'
-
index.js
集global.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.
所以在你的情况下:
- 加载入口点模块index.js,依赖source.js
- 加载source.js模块,依赖class1.js和class2.js
- 加载class1.js模块,依赖constants.js
- constants.js 模块已加载,不依赖任何东西,因此被评估。这会将
'foo'
分配给foobar
变量。 - 至此class1.js的依赖已经满足,执行
- (假设 class2.js 看起来类似于 class1.js),class2.js 模块已加载,并依赖于 constants.js。这已经初始化,所以 class2.js 被执行。
- 至此source.js的依赖已经满足,执行
- 既然满足了index.js的依赖,就执行了。这会将
'bar'
分配给foobar
变量。
当然,模块的全部目的是当你不使用全局变量时,你应该需要对此进行推理:-)