导入的 ES6模块是否在导入的文件中执行代码?

Js 文件中的代码是否在导入期间运行? 如果是,那么是一次还是每次? e.g.

// a.js
console.log("A");
const a = "a";
export default a;


// b.js
import a from "./a"; // => console logs?


// c.js
import a from "./a"; // => console logs again?
35522 次浏览

是的,就一次。

http://www.ecma-international.org/ecma-262/6.0/#sec-abstract-module-records:

如果此模块已被计算,则不执行任何操作。否则,传递地计算此模块的所有模块依赖关系,然后计算此模块

如果有人在 "module": "es6"中使用 TypeScript 并想知道如何做到这一点,请使用 globalThis关键字:

function outputMsg(msg: string) : void {
console.log(msg);
}


// export function for global scope
globalThis.outputMsg = outputMsg;

然后像往常一样在 Chrome DevTools 控制台调用 outputMsg("my console output"),它会自动完成并运行你的函数。

You could also rename your "global export":

globalThis.myCrazyFunc = outputMsg;

并在控制台中调用 myCrazyFunc("crazy message")

一个模块只有在 但是有可能在一个项目中安装同一个模块的两个副本时才会被计算,在这种情况下,该模块及其中的代码将被执行两次。

考虑以下软件包结构:

index.js
package.json
node_modules/
├── package_b/
│   └── node_modules/
│       └── package_a/
|           └── index.js
└── package_c/
└── node_modules/
└── package_a/
└── index.js

如果顶级 Index.jspackage_bPackage _ c导入,那么 包裹 _ a将被导入(并因此进行评估) 两次

Most people are not aware of this behaviour yet probably need to be if they landed on this particular question.

下面是一篇关于 理解 npm 依赖模型的老文章,但是很好,它进一步详细介绍了 npm 是如何以及为什么这样做的。