web-dev-qa-db-ja.com

ES6モジュールのインポートは停止されていますか?

新しいES6モジュールの構文では、JavaScriptエンジンは評価すべてのインポート/エクスポートについて知るためのコードではなく、parse itおよび“何をロードするかを知っています。

これは巻き上げのように聞こえます。 ES6モジュールは吊り上げられていますか?もしそうなら、それらはすべてコードを実行する前にロードされますか?

このコードは可能ですか?

import myFunc1 from 'externalModule1';

myFunc2();

if (Math.random()>0.5) {
    import myFunc2 from 'externalModule2';
}
37
gilamran

さらに調査を行った結果、次のことがわかりました。

  • 輸入品が吊り上げられています! spec ofModuleDeclarationInstantiation
  • コードを実行する前に、すべての依存モジュールがロードされます。

このコードにはエラーがなく、動作します:

localFunc();

import {myFunc1} from 'mymodule';

function localFunc() { // localFunc is hoisted
    myFunc1();
}
24
gilamran

SyntaxErrorになります。 仕様のこの部分 によると:

Module :
   ModuleBody

ModuleBody :
    ModuleItemList

ModuleItemList :
    ModuleItem
    ModuleItemList ModuleItem

ModuleItem :
    ImportDeclaration
    ExportDeclaration
    StatementListItem

モジュールには、ImportDeclarationExportDeclaration、またはStatementListItemのみを含めることができます。 thisStatementListItemによると、ImportDeclarationExportDeclarationも含むことができませんでした。

import myFunc1 from 'externalModule1'; 

インポート宣言ですが、

if (Math.random()>0.5) {
    import myFunc2 from 'externalModule2';
}

ステートメントです。したがって、コードは構文エラーになります。

「コードを実行する前に、それらはすべて読み込まれますか?」 仕様のこの部分 次の文を含む:

注:モジュールをインスタンス化する前に、要求されたすべてのモジュールが利用可能である必要があります。

ええこれらはすべて、コードを実行する前にロードされます

25
alexpods

ES6仕様は変更される可能性がありますが、 このドラフト は明示的です:

静的変数の解決とリンクパスは、インポートされた変数名の競合をチェックします。 2つのインポートされた名前、またはインポートされた名前と別のローカルバインディングの間に矛盾がある場合、コンパイル時エラーです。

ES6だけでなく、実行時にインポートしようとすることは疑わしい考えです。下書きからも:

コンパイルは、すべての変数の定義と参照を解決および検証します。リンクはコンパイル時にも発生します。リンクは、すべてのモジュールのインポートとエクスポートを解決および検証します。

BabelのES6実装 はあまり満足していないことがわかります。

3
Estus Flask