ES6 模块导入是否挂起?
Are ES6 module imports hoisted?
我知道在新的 ES6 模块语法中,JavaScript 引擎将不必 评估 代码来了解所有 imports/exports,它只会解析它并“知道”加载什么。
这听起来像是吊装。 ES6模块是否吊装?如果是这样,它们会在 运行 代码之前加载吗?
这个代码可以吗?
import myFunc1 from 'externalModule1';
myFunc2();
if (Math.random()>0.5) {
import myFunc2 from 'externalModule2';
}
ES6 规范可能会发生变化,但 this draft 是明确的:
The static variable resolution and linking pass checks for conflicts
in imported variable names. If there is a conflict between two
imported names, or an imported name and another local binding, then it
is a compile-time error.
并且尝试在运行时导入是值得怀疑的想法,不仅在 ES6 中。同样来自草稿:
Compilation resolves and validates all variable definitions and
references. Linking also happens at compile-time; linking resolves and
validates all module imports and exports.
你可以看到Babel's ES6 implementation对此不太满意。
这将是一个语法错误。根据 this part of specification:
Module :
ModuleBody
ModuleBody :
ModuleItemList
ModuleItemList :
ModuleItem
ModuleItemList ModuleItem
ModuleItem :
ImportDeclaration
ExportDeclaration
StatementListItem
表示模块只能包含ImportDeclaration
、ExportDeclaration
或StatementListItem
。
根据thisStatementListItem
可以
不包含 ImportDeclaration
或 ExportDeclaration
。
import myFunc1 from 'externalModule1';
是进口申报,而:
if (Math.random()>0.5) {
import myFunc2 from 'externalModule2';
}
是一个声明。所以你的代码会导致语法错误。
那"will they all be loaded before running the code?"呢。 This part of specification 包含下一句:
NOTE: Before instantiating a module, all of the modules it requested must be available.
所以,是的。 它们都会在运行代码之前加载。
经过更多研究,我发现:
- 导入已暂停!根据ModuleDeclarationInstantiation
的spec
- 所有依赖模块将在 运行 任何代码之前加载。
此代码不会有任何错误,并且可以运行:
localFunc();
import {myFunc1} from 'mymodule';
function localFunc() { // localFunc is hoisted
myFunc1();
}
我知道在新的 ES6 模块语法中,JavaScript 引擎将不必 评估 代码来了解所有 imports/exports,它只会解析它并“知道”加载什么。
这听起来像是吊装。 ES6模块是否吊装?如果是这样,它们会在 运行 代码之前加载吗?
这个代码可以吗?
import myFunc1 from 'externalModule1';
myFunc2();
if (Math.random()>0.5) {
import myFunc2 from 'externalModule2';
}
ES6 规范可能会发生变化,但 this draft 是明确的:
The static variable resolution and linking pass checks for conflicts in imported variable names. If there is a conflict between two imported names, or an imported name and another local binding, then it is a compile-time error.
并且尝试在运行时导入是值得怀疑的想法,不仅在 ES6 中。同样来自草稿:
Compilation resolves and validates all variable definitions and references. Linking also happens at compile-time; linking resolves and validates all module imports and exports.
你可以看到Babel's ES6 implementation对此不太满意。
这将是一个语法错误。根据 this part of specification:
Module :
ModuleBody
ModuleBody :
ModuleItemList
ModuleItemList :
ModuleItem
ModuleItemList ModuleItem
ModuleItem :
ImportDeclaration
ExportDeclaration
StatementListItem
表示模块只能包含ImportDeclaration
、ExportDeclaration
或StatementListItem
。
根据thisStatementListItem
可以
不包含 ImportDeclaration
或 ExportDeclaration
。
import myFunc1 from 'externalModule1';
是进口申报,而:
if (Math.random()>0.5) {
import myFunc2 from 'externalModule2';
}
是一个声明。所以你的代码会导致语法错误。
那"will they all be loaded before running the code?"呢。 This part of specification 包含下一句:
NOTE: Before instantiating a module, all of the modules it requested must be available.
所以,是的。 它们都会在运行代码之前加载。
经过更多研究,我发现:
- 导入已暂停!根据ModuleDeclarationInstantiation 的spec
- 所有依赖模块将在 运行 任何代码之前加载。
此代码不会有任何错误,并且可以运行:
localFunc();
import {myFunc1} from 'mymodule';
function localFunc() { // localFunc is hoisted
myFunc1();
}