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