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

use*_*818 45 javascript ecmascript-6

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

// 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?
Run Code Online (Sandbox Code Playgroud)

小智 45

是的,确实只有一次.你为什么不试试呢?

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

如果此模块已经过评估,则不执行任何操作.否则,传递性地评估该模块的所有模块依赖性,然后评估该模块

  • “为什么你只是尝试一下,结果却搞砸了”与“保证每次都会出现这种行为,无一例外”之间是有区别的;) (6认同)
  • @ user2520818:*"如果此模块已被评估,则不执行任何操作.否则,可以传递评估此模块的所有模块依赖关系,然后评估此模块."*http://www.ecma-international.org/ecma-262/6.0 /#仲抽象模块记录 (3认同)

and*_*sit 9

接受的答案并不完全正确。一个已安装的模块在导入时会执行一次,是的,但是如果模块被安装多次(这在 node 中很容易做到),那么它会执行多少次安装。

考虑如果a.jsb.jsc.js位于三个单独的包(package_apackage_bpackage_c)中并且package_bpackage_c都指定package_a作为依赖项,并且您的项目指定package_bpackage_c 会发生什么情况

node_modules/
??? package_b/
?   ??? node_modules/
?       ??? package_a/
|           ??? a.js
??? package_c/
    ??? node_modules/
        ??? package_a/
            ??? a.js
Run Code Online (Sandbox Code Playgroud)

因为package_a将被安装两次(就您的项目而言,这是两个完全不同的包)a.js 中的代码将被导入,因此执行两次

许多登陆这个问题的人不太可能意识到这个节点的怪癖,但如果他们登陆这个问题,可能需要知道。

这是一篇关于理解 npm-dependency-model的旧但很好的文章,详细介绍了 npm 如何以及为什么这样做。

  • 我认为这个答案具有误导性和错误性。问题标题给出的适用规范是 ECMAScript 6,而不是“npm 依赖模型”。具体来说[模块语义](https://262.ecma-international.org/6.0/#sec-module-semantics)和[HostResolveImportedModule](https://262.ecma-international.org/6.0/#sec-hostresolveimportedmodule )。即使对于“npm”,链接的文章也谈到了模块的“副本”(例如不同版本、不同路径、在自己的沙箱中运行)。因此,即使对于“npm”,相同的模块代码也不会运行两次。 (4认同)