Panda Noir

JavaScript の限界を究めるブログです。

Rollupは循環参照をうまくさばけないことがある

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すべて書き出せば解決できます。

https://github.com/rollup/rollup/issues/1089 この循環参照の問題はここでちょうど議論中です。今後のアップデートに期待しましょう。