我知道在新的ES6模块语法中,JavaScript引擎不必评估代码来了解所有导入/导出,它只会解析它并“知道”要加载什么。
这听起来像是在吊装。 ES6模块是否悬挂?如果是这样,在运行代码之前它们都会被加载吗?
这段代码可以吗?
import myFunc1 from 'externalModule1';
myFunc2();
if (Math.random()>0.5) {
import myFunc2 from 'externalModule2';
}
答案 0 :(得分:24)
这将是一个SyntaxError 。根据{{3}}:
Module :
ModuleBody
ModuleBody :
ModuleItemList
ModuleItemList :
ModuleItem
ModuleItemList ModuleItem
ModuleItem :
ImportDeclaration
ExportDeclaration
StatementListItem
这意味着该模块只能包含ImportDeclaration
,ExportDeclaration
或StatementListItem
。
根据{{3}} StatementListItem
可以
不包含ImportDeclaration
或ExportDeclaration
。
import myFunc1 from 'externalModule1';
是一个导入声明,而:
if (Math.random()>0.5) {
import myFunc2 from 'externalModule2';
}
是一份声明。因此,您的代码将导致语法错误。
“在运行代码之前它们都会被加载吗?” this part of specification包含下一句话:
注意:在实例化模块之前,它所请求的所有模块都必须可用。
所以,是的。 在运行代码之前将全部加载。
答案 1 :(得分:23)
在做了一些研究后,我发现:
此代码没有错误,并且可以正常工作:
localFunc();
import {myFunc1} from 'mymodule';
function localFunc() { // localFunc is hoisted
myFunc1();
}
答案 2 :(得分:3)
ES6规范是一个需要改变的主题,但this draft是明确的:
静态变量解析和链接传递检查冲突 在导入的变量名称中。如果两者之间存在冲突 导入的名称,或导入的名称和另一个本地绑定,然后它 是一个编译时错误。
尝试在运行时导入是一个值得怀疑的想法,不仅仅是在ES6中。也来自草案:
编译解析并验证所有变量定义和 引用。链接也发生在编译时;链接解决方案和 验证所有模块导入和导出。
您可以看到Babel's ES6 implementation对此并不满意。