JavaScript
babel
flowtype
mobx

transform-flow-strip-types と transform-decorators-legacy を同時に使う時、気をつけること

More than 1 year has passed since last update.

transform-decorators-legacy でデコレータと transform-flow-strip-types で flowtype を一緒に使う場面ありますよね。

このとき、プラグイン定義の順序が重要になってきます。


誤: transform-flow-strip-types を先に定義する

この場合、特定の場合におかしくなります。

  "plugins": [

"transform-flow-strip-types",
"transform-decorators-legacy"
],

具体例として、mobx の @observable を使ってみましょう。

class Counter {

@observable count: ?number;
}

これの babel のトランスパイル後のコードはコチラ。

var Counter = function Counter() {

(0, _classCallCheck3.default)(this, Counter);
};

わー。見事に observable な定義が無かったことになっていますね。ちなみに

class Counter {

@observable count: ?number = null;
}

と初期値が undefined でなく null だった場合

var Counter = exports.Counter = (_class = function Counter() {

(0, _classCallCheck3.default)(this, Counter);

_initDefineProp(this, "count", _descriptor, this);
}, _descriptor = _applyDecoratedDescriptor(_class.prototype, "count", [_mobx.observable], {
enumerable: true,
initializer: function initializer() {
return null;
}
}), _class);

とバッチリ定義されるので、ハマったときにさらに解りにくかったります。というか自分が @observable だけど上手く動いたり動かなかったりする現象で何が問題なのかを見つけるまでハマりました…。


正: transform-flow-strip-types を後に定義する

  "plugins": [

"transform-decorators-legacy",
"transform-flow-strip-types"
],

この定義の場合、デコレータの処理が先にされるため

class Counter {

@observable count: ?number;
}

のトランスパイル後のコードが

var Counter = exports.Counter = (_class = function Counter() {

(0, _classCallCheck3.default)(this, Counter);

_initDefineProp(this, "count", _descriptor, this);
}, _descriptor = _applyDecoratedDescriptor(_class.prototype, "count", [_mobx.observable], {
enumerable: true,
initializer: null
}), _class);

と、undefinded だったとしても mobx.observable な処理がされ、適切に動作します。