タオルケット体操

サツバツいんたーねっとでゲームとかガジェットのレビューとかをします

Fluxで消耗するために自分でFluxフレームワークを作ってみた(Amamoriといいます)

場所

ギッハブにあります。

github.com

作った動機

Fluxフレームワーク、色々出てきては消えるしReduxとかが提唱されるしでもうわけわかめ。これからアタシ(のプロジェクト)、一体どーなっちゃうの〜〜?!

APIリファレンスみて色々と見比べてるだけの中途半端な知識だと、いざ自分が選んだフレームワークが死んだ時に潰しが利かない…… -> じゃあ一度自分で作ってみよう!

あと社内にFluxわかるマンがいなかったので、公開して広く世間の意見を求めたいという気持ちも強かった。なんかおかしいところあったら教えてくだされ〜〜〜

というわけで作った。
あとES6で書いたコードをnpmモジュールで公開する方法を知りたかったというのもある。

大変だったところ

Fluxを実際に実装に落とし込める感じに理解するのが大変だった。
理解するために、Facebookの概念図をみたり、azu氏の実装(GitHub - azu/material-flux: No magic flux implementation library.)を参考にしたりした。

npmモジュールの公開方法が大変だった。
特に、AltJSで書いたものを公開する方法とか、ちゃんとモジュールになっているかをテストするほうほうとかが完全にわけわからんくて悲しい気持ちになった(まだ完全に理解してはいない)。
pypiとかgemとかは書いたことがあるんだけども、JavaScriptはコンパイルの手間とかが入るせいでモジュールの公開が複雑になるっていうのはあるとおもう。

正直、flux作るよりもnpmモジュール作る方がめんどくさくて公開が遅れたみたいなところはある。

コンセプト

とにかく全て明示的で愚直なAPIにして、めんどくさいところはReactとかに任せちゃえばいいじゃんみたいなコンセプト。
ちゃんとFluxになっているつもりだけど、間違ってたらすみません。

コード量を減らすための便利APIみたいなものがほとんどないので、値の受け渡しとかの実装がめちゃくちゃダサくなるけど、読んでわかりやすいのでいいんじゃなかろうか。

微妙に認証周りのユーティリティとか入れちゃったけど、モジュール分離したほうがいいかもしれん。

TypeScriptで書きたかったけど、なんかコンパイルとか辛かったので省略。.d.tsは書きたい。

今後の課題

Dispatcherってグローバルに一個あればいいんだろうか。
現状の明示的にDispatcherを受け渡しするAPIはダサいので、シングルトンでいいならばもうちょっと記述が楽になるかもしれん。

あとテストがない。

感想

ES6でclass入ったとか喜んでたけど、冷静に考えるとmix-inか多重継承の構文レベルでのサポートないと使い物にならなくね? 現状のclass機能だと、真面目にオブジェクト指向やろうとしたら結局prototypeいじくらないとだめじゃね? つらくね?

最初はsetStateが連続で呼ばれまくったときに非同期ぶっこわれたりレンダリング入りまくって死ぬんじゃね? とかおもって適当に間引くstack作ろうとかしてたけど、Reactの実装チラ見したらそこらへんはすでに考慮されてたのですごい。 とにかくReactに任せられる部分はReactに任せておくことで学習コストが削減できて良いのではとおもった。

あんまり他の実装を比べられてないので、色々と参考にして改善していこうとおもった(小学生並みの感想)。

*追記

Fluxわからんとか言ってた日記から1年経っててワロタ。ワロタ……

  • Dispatcherをシングルトンにせず実装から隠蔽するにはcontextを使えば良さそう

    React の Context を使って Flux を実装する - Qiita

    contextを使う形式にしたらDispatcherを隠蔽できたのでよかった。Componentの階層構造に依存してしまうけど、普通のプロジェクトはDispatcher一つで事足りるだろうし、そもそもComponentの階層構造がそうあるべきなので特に問題なさそう。

  • mix-inも多重継承も(構文レベルでのサポートが)なく、小手先のテクニックでどうにかしないといけない現状はどう考えても正気じゃないというか、糖衣構文とはいうものの本当にそれ以上でもそれ以下でもないという印象なので、あまり期待せず割り切って使うのが正しいのかもしれない。
    ユーザが使う部分だけをclass syntaxで使うようにしておいて、自分でオブジェクト指向したい場合はプロトタイプをいじるか、オブジェクトとか諦めてカンスウガタオリエンテッド脳にやるみたいなことになるのかなという所感。

*追記2

Component.contextを使って子Componentへ自動的にDispatcherを渡すように修正した。

ついでにComponentに紐づくStoreを宣言的に記述できるようにしておいて、Storeの変更が自動的にstateへと反映されるように修正。

class TodoView extends Component {
  static get storeTypes() { return [NewTodoStore, TodoStore] }

こんな感じでStoreを宣言できる。
もちろん、親Componentからprops経由でstoreを渡してもいいんだけど、子Componentをstatefulにすることってあんまりなさそうなのでそこまで考慮してない。
その他いろいろ修正して、定型コードは減ったようにおもう。