2016-05-29 10 views
14

JavaScriptアプリケーションでES6モジュールを使用しています。ソースはwebpackとbabelでコンパイルされています。これは私にトラブルを引き起こすファイルの短縮バージョンです:ES6モジュール:インポートされた定数は、最初は定義されていません。後で使用できるようになります

export const JUST_FORM = 0; 
export const AS_PAGE = 1; 

console.log(AS_PAGE); // ** 

export default function doSomething(mode = AS_PAGE) { 
    console.log(mode); 
    console.log(JUST_FORM); 
} 

私はこの機能を期待通りに使います。

import doSomething, { AS_PAGE } from './doSomething' 

console.log(AS_PAGE); 

doSomething(); 

私はアプリを実行すると、それが三回undefinedを印刷し、唯一**が付いconsole.logで期待値AS_PAGE一回。しかし、これは最後に印刷されます!

  • AS_PAGE定数は、doSomething function`のデフォルトパラメータとして使用される場合、関数を定義する瞬間に定義されていない:それはことを示しています。
  • doSomethingを呼び出すと、定数は定義されません。
  • AS_PAGE定数は、明示的にインポートすると定義されません。

明らかに、defaultのエクスポートだけが解析され、評価され、残りのファイルは後で無視されます。私はこのファイルを私のアプリのいくつかの異なる場所にインポートします(現時点ではかなり大きい)、ある時点でそれらの値が実際に利用可能になります。コンソール出力から判断すると、時間の問題ですが、別の理由がある可能性があります。明らかに、私はすべての場所でまったく同じようにインポートを行います。

とにかく、私が何かを読み込んだらすぐに利用できると私のコードでそれを使うことができるという前提で、私はアプリケーション全体を書いてきました。私はES6モジュールがどのように動作すべきかについて(簡単に)読んでおり、この仮定が間違っていることを証明するものは見つけられませんでした。それまでは今まで働いていました。

また、webpack-dev-serverで実行したり、単一のバンドルにコンパイルしたときの動作は同じです。

この動作は本当に正しいですか?それは何が原因でしょうか?

+4

循環依存関係。 – Bergi

+0

@Bergi私は盲目でなければなりません、循環依存はどこですか? –

+0

@torazaburo:彼が投稿したコードではありませんが、これはこの動作の原因です。私は賭けるよ。 – Bergi

答えて

14

コメントに示唆されているように、ここの答えは循環依存性です。

質問で提供されたコードには実際には循環依存はありませんが(単純なコードスニペットなので)、症状は非常に明確です。

循環依存の最も単純な例は、ファイルAがファイルBをインポートし、ファイルBがAをインポートする場合です。残念ながら、この問題を時々検出するのが難しいのは、円が任意の大きさで、膨大な量のファイル。

循環依存関係はES6でサポートされ、1つは十分に気をつけているとき、彼らが使用することができます。しかし、私がここで取り上げるのは、循環依存が非常にしばしば設計上の意思決定の悪い兆候であるということです。それはまさに私の場合だった。

関連する問題