react-vue-native-scriptsで始める、Vue.jsでのReact Nativeアプリケーション開発

[10月6日のGotanda.js](https://gotandajs.connpass.com/event/66262/)で話した、[react-vueについての発表](https://docs.google.com/presentation/d/152fLpUOcEhjhdnqJQXq_d1s6mJ2kFv0C_Xj4Z0egP00/edit)で、やってみたいと言っていたreact-vue-native-scriptsをまだ試せていなかったので使ってみようと思いました。

[以前WeexでWebSocketを使用したチャットを作った](https://github.com/syumai/wee-chat)時は、非常に辛い思いをしたので、今度こそは快適な開発生活を送れるのではと期待しています。

## [react-vue](https://github.com/SmallComfort/react-vue)とは

* Vue.jsのコンポーネントをReactアプリケーションの中で普通に使えるようにする
  - [`react-vue-loader`](https://github.com/SmallComfort/react-vue-loader)とかを使います
* 逆にReactのコンポーネントをVue.jsの中で使うこともできる
* 最終的にはReactの上に載せる必要あり

と言った内容の
悪魔的な
プロジェクトです。
React Nativeもサポートしているらしいので、ワクワクです！
(※…react-vue自体は、しばらく開発も更新も止まっているので、遊びだけで使うようにしましょう)

## 今回作るもの

Firebaseを利用したチャットアプリを作ってみようと思います。

## 導入

* [React Native の Getting Started](https://facebook.github.io/react-native/docs/getting-started.html)に従って、create-react-native-appでプロジェクトを作成します
  - `yarn global add create-react-native-app`
  - `create-react-native-app ReactVueNativeChat` (例)
* 生成されたプロジェクトのディレクトリに入り、下記の通りに3つのパッケージをインストールします
  - `yarn add react-vue react-vue-helper`
  - `yarn add --dev react-vue-native-scripts`
* package.jsonのscriptsに以下のコマンドを追加します
  - `"compiler": "react-vue-native-scripts compiler"`

以上で導入完了です！簡単！

## 開発

開発を開始する際は、以下の2つのコマンドを実行します。

* `yarn start`
* `yarn compiler`

`yarn start`で起動するのは、いつもの`react-native-scripts`の`start`コマンドで、Expoの読み込み用のQRコード等が出てきます。

`yarn compiler`コマンドを実行すると、`react-vue-native-scripts`のコンパイラが起動して、`*.vue`ファイルを、同名の`*.js`ファイルとして、**React Componentに変換してくれます**。

なので、開発中は上記2つを起動しっぱなしにしておきます。

### 単一ファイルコンポーネント、どこまで使えるのか?

実際に使うにあたって、

* スタイルの指定はどこまで出来るか
* templateやstyleで別言語(Pug, Stylus等)を指定できるか

などを検証したいと思いました。

実際に動いた`*.vue`ファイルは以下の通りです。

```html:src/components/Hello.vue
<template>
  <view class="row">
    <view class="column">
      <text class="left">
        Hello, world!
      </text>
    </view>
    <view class="column">
      <text class="right">
        Hello, world!
      </text>
    </view>
  </view>
</template>

<script>
export default {};
</script>

<style>
.row {
  flex: 1;
  flex-direction: row;
}

.column {
  flex: 1;
  justify-content: center;
  align-items: center;
}

.left {
  color: #ff0000;
  font-size: 12;
}

.right {
  color: #0000ff;
  font-size: 16;
}
</style>
```

エントリーポイント(App.js)は下記の感じになりました。

```js:App.js
import React from 'react';
import Hello from './src/components/Hello';

export default () => <Hello/>;
```

#### 分かったこと

* `view`, `text`などのReact Nativeコンポーネントはimportしなくても使える
* styleの指定は、クラスベースでしか出来ない
  - 要素名での指定は駄目
  - ネストも無理
  - 複数のクラスを付けるのはアリっぽい

現状では上記の様な対応状況になっているようです。(これだけでも嬉しいですが…。)

あと、Pugも試してみましたが、`react-vue-template-compiler`が構文解析でコケてたっぽいので、使用できませんでした。。
Stylusに関しては、そもそもCSSのクラスのネストが出来ないっぽい事から、試す意味があんまり無さそうだったので一旦スキップしています。

とは言え、React Nativeっぽいスタイリング(Objectでスタイル宣言して、Componentのstyle propに渡す)から解放されることで、よりWebに近い感覚で開発出来るようにはなっているのではないかと思います。(間違いなく個人差はあります) 

## 実際に作ってみる

ここまでで、持ち駒が揃ったので、開発してみようと思います！
ちゃんと終わってたら本日中に公開される予定です。。

**以下、WIP...**

## 仕様

### イメージ

今回は、LINEっぽいやつを作ってみようと思います。

### 画面構成

* ログイン画面
* 友だち一覧
* トーク一覧
* トーク画面

友だち一覧、トーク一覧をタブに押し込む感じのイメージですね。

トーク画面は、ストイックに行きたいので[react-native-gifted-messenger](https://github.com/FaridSafi/react-native-gifted-chat)抜きで、全部自前で作ろうと思います。

#### LINEのトーク画面スクショ

![Screenshot_20171209-172421.png](https://qiita-image-store.s3.amazonaws.com/0/45427/73efa2e4-5bdb-a457-dc4a-d299470d475c.png)

この画面には部分的にしか無いですが、LINEのトーク画面の特徴は、

* 連続してメッセージを送っても吹き出しの形が変わらない
* 同じ時間に送っても全部時刻が表示される
* と言うか、タイミングに関わらず全て同じ表示で出るっぽい

なので、わりと真似しやすいのではないかと見込んでます…。

### 機能上の特徴

* 既読機能
* 画像の送信

あたりがやれたらいいなと思ってます。

### アプリケーション構成

* 状態管理 => Vuex
* 画面遷移 => react-navigation
* チャット用サーバー => Firebase

で作ろうと思います。既に色々混ざって来ていますが、
react-navigation + Vuexについては、[SmallConfort氏によるHackerNewsアプリの実装](https://github.com/SmallComfort/HackerNews)と言う心強い例があるので、こちらを参考にします。

#### 以下、作業途中です（随時更新予定）

### リポジトリ

https://github.com/syumai/react-vue-native-chat

### ToDoリスト
- [ ] データ設計
- [ ] Firebase導入
- [ ] Vuex導入
- [x] react-navigation導入
- [x] ログイン画面
- [ ] 友だち一覧
- [ ] トーク一覧
- [ ] トーク画面


### ログイン画面出来ました(12/09 22:50)

<img width="180" alt="スクリーンショット 2017-12-10 22.46.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/45427/6b79c1f6-cdf7-405b-a8e9-1215d52f506e.png">

とりあえず気分を高めていくためにそれっぽいログイン画面を作りました。
まだVuex、Firebaseとフォーム連携してませんが、ログインボタン押したらとりあえず次に遷移します！