MeteorにReact+Reduxのせてクロスプラットフォーム&フルJavaScriptなアプリケーション

## **概要**

MeteorにReduxをのせて、フルJavaScriptなアプリケーションをつくりたく、そのboilerplateを作ってみた。インストールなど詳細はGithubにある。

* <a href="https://github.com/okmttdhr/meteor-react-redux-boilerplate" target="_blank">okmttdhr/meteor-react-redux-boilerplate</a>

Meteor、Reduxについては以下が易しい。

* <a href="http://www.slideshare.net/rukiadia/meteor-47398816" target="_blank">Meteorというフレームワーク</a>
* <a href="http://qiita.com/m0a/items/cf7a57face7a0e264881" target="_blank">リアルタイムWebアプリケーションフレームワークMeteorについて - Qiita</a>
* <a href="http://amagitakayosi.hatenablog.com/entry/2015/07/30/000000" target="_blank">人気のFluxフレームワークReduxをさわってみた - マルシテイアは月の上</a>

Meteorはフルスタックなだけあって、綺麗に使おうとするとMeteor Wayな感じになってしまう。それはそれでいいのだけど、普段SPAを開発しなれている環境をMeteorにのせられたら構成を考えなくて済む。今後Meteorでアプリケーションをつくる際も(あるのかな)、アーキテクチャをつくるコストが下がるのではと考えた。



## **スタック**

使った技術は以下のとおり。

* <a href="https://github.com/meteor/meteor/" target="_blank">Meteor</a>
* <a href="https://github.com/facebook/react" target="_blank">React</a>
* <a href="https://github.com/rackt/react-router" target="_blank">React Router</a>
* <a href="https://github.com/rackt/redux" target="_blank">Redux</a>
* <a href="https://github.com/babel/babel" target="_blank">Babel</a>
* <a href="https://github.com/webpack/webpack" target="_blank">Webpack</a>
* <a href="https://github.com/mochajs/mocha" target="_blank">Mocha</a>



## **プロジェクト構成**

全体の構成としては、以下の様な感じ。

①`.client`フォルダ配下に、React+Reduxのクライアントコードがあり、webpackで`client`配下にビルド、②さらに、ビドルされたJSを、Meteorがうまいことやってくれる。

```bash
├── index.html
├── .client           # client application code
├── .meteor
├── client
│   └── bundle.js     # bundled file by webpack
└── lib
    └── models
        └── todo.js
```

webpackだけだと、Meteorの便利な機構がうまく使えないし、Meteorだけだと、基本グローバルにいろいろつくっていく感じで、モジュール化に限界があるように感じたため、このようにしている。

フォルダ名は、Meteor側でビルドする際の順番があるので、それに沿って作っている。

* <a href="http://docs.meteor.com/#/full/structuringyourapp" target="_blank">Structuring your app - Meteor Documentation</a>

`.client`配下はMeteorには読まれないため、好きにディレクトリを組むことができ、<a href="https://github.com/zhongqf/meteor-react-redux-example" target="_blank">meteor-react-redux-example</a>を参考に以下の様な構成を組んでいる。

```bash
# in .client folder

├── actions
│   └── Todo.js
├── components
│   ├── TodoAdd.js
│   ├── TodoApp.js
│   ├── TodoEdit.js
│   └── TodoItem.js
├── constants
│   └── index.js
├── containers
│   ├── DevTools.js
│   ├── DevToolsWindow.js
│   └── Root.js
├── initialStates
│   └── index.js
├── layouts
│   └── CoreLayout.js
├── reducers
│   ├── Todo.js
│   └── index.js
├── routes
│   └── index.js
├── store
│   └── configureStore.js
├── styles
│   ├── _base.scss
│   ├── core.scss
│   └── vendor
│       └── _normalize.scss
├── utils
│   └── index.js
├── views
│   └── HomeView.js
├── test
│   ├── actions
│   │   └── todo.js
│   ├── components
│   │   └── todo.js
│   ├── helper
│   │   ├── index.js
│   │   └── mock.js
│   └── index.js
├── config
│   ├── index.js
│   └── webpack.js
├── index.js
├── package.json
└── webpack.config.js
```

これにて、迷うことなくReduxで開発をすることができる。


## **通常のReduxと違う点**

### リアルタイムなモデル

Meteorのリアクティブな機構を使い、以下の様な感じでMongoDBからリアルタイムにデータを読み込むことができる。

読み込まれたデータは、接続された全てのクライアントでリアルタイムに同期される。

```javascript
const HomeView = React.createClass({
  mixins: [ReactMeteorData],

  getMeteorData() {
    return {
      todos: Todos.find({}).fetch(),
    };
  },

  render () {
    return (
      <div className='HomeView'>
        {JSON.stringify(this.data.todos)}
      </div>
    );
  },
});
```

また、データの更新なども以下のように簡単に行うことができる。

```javascript
Todos.update(action.id, {$set: {text: action.text}});
```

このあたりで、Reduxいらないんじゃね?とも思った(気づくの遅い)が・・・DBから取得しないデータの場合に、手軽に実装できるのはありがたい。また、どこにどんな処理を書くかがおおよそ明確なので、設計に困らないというのも利点である。

### モバイル対応

Meteorはマルチプラットフォームで動くようにつくられているので、JavaScriptアプリケーションをモバイルアプリ化することもできる。

ここでは`npm run ios`によって、simulatorでiOSアプリがビルドされるようにしている。

![スクリーンショット 2015-11-13 12.05.58.png](https://qiita-image-store.s3.amazonaws.com/0/22875/030b426f-e1d4-420b-b3ee-28a45eb1412a.png)

![スクリーンショット 2015-11-13 11.58.35.png](https://qiita-image-store.s3.amazonaws.com/0/22875/1e4ad00c-44be-2cdf-b90f-3747528b04dc.png)


## **その他**
### デプロイ

現状では`meteor deploy`を使っているだけなので、プロダクションで使うならいろいろ検討する必要がある。

### セキュリティ

このへんをみていい感じにする必要がある。

* <a href="https://www.meteor.com/tutorials/blaze/security-with-methods" target="_blank">Meteor Tutorial | Security with methods</a>

## **雛形検討**

検討したひな形をメモしておく。

### <a href="https://github.com/thereactivestack/kickstart" target="_blank">thereactivestack/kickstart</a>

180 stars

#### simple

* 良い。シンプルだし、いろいろ改良できそう。
* Meteor.methodsとかあるのはいいけど、結局、Meteor側でモジュール化の仕組みが強くないからそういう機能がある感。
* その点Reduxはreducerに書くという明確な指針があるからよい。
* サーバーサイドレンダリングを実装している

#### hugeapp

kickstart-simpleに、モジュールを追加していく感じ。Meteor Way感がある。

#### flowrouter: ✕

flowrouterは今回は除外。

### <a href="https://github.com/zhongqf/meteor-react-redux-example/" target="_blank">zhongqf/meteor-react-redux-example</a> & <a href="https://github.com/zhongqf/meteoredux" target="_blank">zhongqf/meteoredux</a>

16 & 6 stars

* Meteor感が限りなくない。すごいいい。
* 現状サーバーサイドレンダリングを実装していない。


### <a href="https://github.com/AdamBrodzinski/react-ive-meteor" target="_blank">AdamBrodzinski/react-ive-meteor</a> 

122 stars

* かなりMeteor Way感ある。modelやaction、domainなど、サーバーサイドの管理もしやすいようになっている。使えるかは微妙だが、フィードアプリを題材に実際のCRUDコードを見ることができるので、基礎的な実装をするのにかなり参考になりそう。

### <a href="https://github.com/AdamBrodzinski/meteor-flux-leaderboard" target="_blank">AdamBrodzinski/meteor-flux-leaderboard</a> 

77 stars

* reduxブランチがかなり参考になる。これ自体は複雑なところがあるので使わないが、つくる際の参考になりそう。
* リアルタイムじゃない・・・?

### <a href="https://github.com/jedwards1211/meteor-webpack-react" target="_blank">jedwards1211/meteor-webpack-react</a>

192 stars

* あんまよくない。結構がんばってるしstarもついているのにコード汚い。バグもあったし、他に比べるとひどすぎた。


## **修正/追加したいこと**

- [ ] MongoDBのテスト
- [ ] autopublishを消す
- [ ] insecureを消す
- [ ] Meteorのaccounts systemいれる
- [ ] サーバーサイドレンダリング
- [ ] コマンドラインもうちょっといい感じに
- [ ] デプロイ、ホスティング

プロダクションで使えたらちょっと楽しそう。