Typescript + React + Redux + SSR 辺りの素振り

仕事で使うことになりそうなので素振り

要点を抑えながらシンプルめに書いてみた

インクリメントするだけのアプリ

セットアップ

基本的なの

$ yarn add react react-dom redux react-redux
$ yarn add --dev typescript ts-loader webpack webpack-cli

型情報も入れる

$ yarn add --dev @types/react @types/react-dom @types/react-redux

サーバー

$ yarn add fastify serve-static
$ yarn add --dev @types/serve-static

ディレクトリ構成

SSRするのでクライアントとサーバー側それぞれでエンドポイントを用意してる

├── app // 共通のコード
├── client
│   └── index.tsx
├── server
│   ├── Html.tsx
│   └── index.tsx
├── tsconfig.client.json
├── tsconfig.json
├── webpack.config.js
└── package.json

最終的なコード

github.com

yarn start するとサーバーが立ち上がって、初回のSSRだけされるようになってる

f:id:rskull:20180827014625g:plain

参考にした記事

ReactNative アップグレード対応 v0.52 -> v0.56

みんな大好き恒例のアップグレードをしたので、その時にハマった事のメモ

今回は v0.52.2 から v0.56.0 にアップグレードした

前回のアップグレードよりは楽だったけど、本体のバグらしき罠にだいぶはめられた

ちなみに前回と同じく $ react-native-git-upgrade は使わずに

$ react-native init myApp で新たに作成したフォルダに自力で差分をみてマージをしてる

なんだかんだこの方法が一番キレイに出来る

差分の確認

念の為、今回のアップデートの差分を目視確認しておく

自分の環境に合わせて差分が見れるので、それを適用すればOK

Comparing rn-0.52.2...rn-0.56.0 · ncuillery/rn-diff · GitHub

AndroidcompileSdkVersion などが上がった対応

おそらくこれが今回の一番大きな変更

  • compileSdkVersion 23 -> 26
  • buildToolsVersion 23.0.1 -> 26.0.3
  • targetSdkVersion 22 -> 26

これにより、依存してるサードパーティが大体 23 のため、警告が出たりビルドが落ちたりする

正しい対策じゃないかもしれないけど

android/build.gradle に以下のコードを追加して対応した

subprojects {
    afterEvaluate {project ->
        if (project.hasProperty("android")) {
            android {
                compileSdkVersion 26
                buildToolsVersion '26.0.3'
            }
        }
    }
}

警告出されたけどビルドは通るようになった

※ 正しい方法があったら教えて下さい!

リリースビルドのアプリを起動すると直後にクラッシュする

こんなエラーが出てた

undefined is not an object (evaluating 'r.default')

結果的にいうと、原因は react-navigaiton だった

PRは却下されてるけど、とりあえずこの修正を適用すると動くようになる

Fix issue undefined is not an object evaluating r.default by ebaynaud · Pull Request #4699 · react-navigation/react-navigation · GitHub

import が正しく出来ないバグっぽいので、根本的な理由は多分 babel7 に移行したことで何か問題が起きてるのかな??

flowのエラー

型が強化されたみたいで、エラーがたくさん出た

気合で直す

CocoaPodsの修正

BatchedBridge がなくなって、代わりに CxxBridge を追加した

   pod 'React', :subspecs => [
      // ...
+    'CxxBridge',
-    'BatchedBridge'
   ], :path => '../node_modules/react-native'

正直このへんよくわからないし触りたくない

Jestが実行できない

Jestを実行すると、そもそも動かなくていろんなエラーがでて落ちる

Issueはこれ

github.com

package.json に以下のコードを追加したら動くようになった

  "jest": {
    "preset": "react-native",
     "transform": {
       "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
     }
  }

これはとりあえずの回避策で

PRはちゃんと出てるみたい: Fix jest-preset to use internal preprocessor (fix testing with 0.56) by vovkasm · Pull Request #20068 · facebook/react-native · GitHub

動くようになった

自分がハマったのはこれくらいです

--

※ 2018/07/25 追記

TextInputの日本語入力が出来ない件

すっかり忘れてたけど、直ってないじゃん!!

今の所、これが最善っぽい?

gist.github.com

元Issue: [iOS][TextInput] Fix controlled TextInput for Chinese (and other languages) by magicien · Pull Request #18456 · facebook/react-native · GitHub

TwitterKitを使ってるアプリでWeb経由の認証が出来なくなったのを解決した

Twitterの仕様変更

本日(2018/06/12)に認証周りの仕様が変わった。

認証して戻ってくる時のコールバックURLをデベロッパーの管理画面で設定するのが必須になった

Callback URL — Twitter Developers

TwitterKitを使ってログインを実装してるアプリで、端末にTwitterが入ってなければブラウザが立ち上がって認証が行われる

その場合、コールバックURLの設定をしてないと認証がコケるようになってしまった

ちなみにReactNativeアプリの開発でTwtiterの認証にreact-native-twitter-signinを使っている

github.com

修正

アプリの管理画面の設定を開く

https://apps.twitter.com/

f:id:rskull:20180612192226p:plain

コールバックURLに

twitterkit-YourConsumerKey:// の形式で登録する

これはTwitterKitがコールバックURLとして使っているもの

YourConsumerKeyは自分のアプリのコンシューマーキー

://を末尾に付けないと登録出来ないので注意

f:id:rskull:20180613123301p:plain

..

f:id:rskull:20180612191828p:plain

登録が終わったら、コールバックをロックしても正常に認証出来るようになった

※ 追記(2018/06/14)

上記の対応だと、AndroidのWeb経由だけ認証が通らなかった

合わせて下記の対応でiOSTwitter経由/Web経由)AndroidTwitter経由/Web経由)すべての経路で認証が通るようになった

ちなみにtwittersdk://の対応だけだとiOSのWeb経由が通らなくなった(僕の環境だと)

この辺の挙動アナウンスないしほんと謎

react-native-domをちょっと動かしてみた

いい加減触るかと思いたち、チュートリアルをしてみた

github.com

セットアップ

適当なサンプルプロジェクトをinitする

$ react-native init rndomExample

まずは普通にアプリを起動してみる

$ react-native run-ios

f:id:rskull:20180526015755p:plain

ふむ

次に本題のセットアップ

$ yarn add --dev rnpm-plugin-dom
$ raect-native dom

パッケージを追加してコマンドを実行すると、新しいファイルが作成される

f:id:rskull:20180526014509p:plain

あとは起動するだけ

$ react-native run-dom

ターミナルが立ち上がって、すぐにブラウザが立ち上がる

f:id:rskull:20180526015927p:plain

ブラウザで同じ画面が表示された

すごい

検証

LayoutAnimationとか動くのかな?と思って動かしてみた

簡単なサンプルだけど、ほぼ完璧に同じ動きしててすごい

左がアプリで右がウェブ

f:id:rskull:20180526024317g:plain

ここまでのソース

GitHub - rskull-sandbox/rndomExample: example for react-native-dom

どうやって動いてるのか?

すごく詳しく仕組みを解説してくださっているので

気になる方はこちらの記事を見てください!

blog.nkzn.info

ここまで理解できるのすごい

これが精一杯(花)