Rollupでは、循環参照していてもビルドしてくれます。しかし、子クラスが2つ以上になると意図した通りにビルドしてくれません。
このケースでは、ビルド自体は通るのですが、エラーが起きるコードが出力されます。ビルドは通ってしまうので、落とし穴に気づきにくくかなり厄介です。
コード
実際のコードがこちら
// main.js import C from './C.js'; import {A} from './A.js'; import {B} from './B.js'; export {A, B, C};
// B.js import {A} from './A.js'; import C from './C.js'; export class B { a() { return new A(); } }
// A.js import {B} from './B.js'; export class A extends B {}
// C.js import {B} from './B.js'; export default class C extends B {};
このように、AとCがBを継承している構造をRollupは正しくビルドしてくれません。
ES2015のクラスでは、extendsしたいクラスはextendsの宣言より前に宣言されていなければなりません。そのため、BがAとCよりも前に宣言されていなければいけません。しかし、RollupはどうやってもBを前に出してくれません。
この問題は子が1つのケースでは起こりません。そのため、AかCどちらか一方のみにすれば、Bが先にきてくれます。
解決方法は?
この問題、 現段階ではあきらめるほかありません。 main.jsにA.js、B.js、C.jsすべて書き出せば解決できます。
この循環参照の問題はちょうどHandling of circular dependenciesというIssueにて議論中です。今後のアップデートに期待しましょう。