Slide 1

Slide 1 text

Capacitor製のWebViewアプリから React Native製のハイブリッドアプリへ @yukukotani 2024/05/30 - React Native Meetup #16

Slide 2

Slide 2 text

小谷 優空 / @yukukotani ・SWE / VP of Technology @ Ubie, Inc. ・React Native 1年生 ・Student @ Univ. Tsukuba 自己紹介

Slide 3

Slide 3 text

趣旨 ・UbieでCapacitor製アプリをReact Native製にリニューアルした ・移行の背景 ・React Nativeでハイブリッドアプリ、どうやるのか

Slide 4

Slide 4 text

目次 1. アーキテクチャ概観 2. 移行の背景 3. ハイブリッドアプリの実装

Slide 5

Slide 5 text

モバイルアプリ誕生以前 ・Next.jsでWebアプリを開発 ・SSRサーバーとして運用 SSRサーバー Web Browser アクセス ビルド Next.js

Slide 6

Slide 6 text

移行前: Capacitorアプリの構成 ・全画面が単一のWebViewでリモート参照 → シンプルにOTAアップデート ・既存のWebアプリをモバイルアプリ向けにビルドし、別ドメインで配信 ・モバイルアプリ向けのビルドからは Capacitor API でネイティブ機能を利用 Web向け サーバー Mobile App向け サーバー Capacitor Web Browser アクセス Capacitor API でネイティブ機能呼び出し ビルド ビルド WebViewでアクセス Next.js 単一コードベースだけど 別ビルド・別インスタンス

Slide 7

Slide 7 text

移行後: React Nativeアプリの構成 ・基本はCapacitorをReact Nativeに置き換えただけ ・一部の画面はReact Nativeで実装しつつ、WebViewも引き続き利用 ・Capacitor APIを代替するブリッジを自作 Web向け ビルド Mobile App向け ビルド Expo (React Native) Web Browser アクセス ビルド ビルド Next.js 自作のブリッジ でネイティブ機能呼び出し 一部画面のみ WebViewでアクセス

Slide 8

Slide 8 text

目次 1. アーキテクチャ概観 2. 移行の背景 3. ハイブリッドアプリの実装

Slide 9

Slide 9 text

前提:Capacitorはめちゃくちゃ良かった Webアプリがある状態でモバイルアプリのポテンシャルを評価する1st stepとして 超おすすめI „ Capacitorのおかげで1週間でモバイルアプリを出せ4 „ その後もアプリ用の工数はほぼゼロで、新機能を継続的にデリバリー

Slide 10

Slide 10 text

なぜ移行したか:MVPを超えて本格開発するため エコシステ% ユーザー体( i Ionic/Capacitorに投資している大企業が少な‰ i 結果としてか、メンテナンスが滞っているものが多‰ i OTAアップデートの仕組みもあるにはあるが、枯れていな‰ i ネイティブ側SDKとWebViewの整合性問題など i WebView 1枚に閉じた表現力の限h i Ionicはよくできているが、言語化しにくい細かい「アプリっぽくなさ」があ… i オフライン対応を進めるために、全面リモートWebViewをやめたい ・体調が悪いユビーのユーザーには、小さな違和感でも引っかかってほしくない

Slide 11

Slide 11 text

なぜReact Nativeハイブリッドアプリか エコシステ s Meta, Microsoft, Amazon, Shopify といったテックジャイアントの安心C s 3rd-partyライブラリも比較的よくメンテナンスされている Expƒ s EASの出来がかなり良€ s さらにRSC対応して最高になると賭けた(実際進んでるっぽくて嬉しいm s Expo SDKも豊富、かつ Managed Workflow でアプデも困りにくい TypeScripš s 引き続きWeb版の資産を生かしたハイブリッドアプリにしたかっÊ s WebViewと言語が揃うことは認知負荷が減る以外のメリットも大きい(後述)

Slide 12

Slide 12 text

目次 1. アーキテクチャ概観 2. 移行の背景 3. ハイブリッドアプリの実装

Slide 13

Slide 13 text

WebViewからのネイティブAPIコール

Slide 14

Slide 14 text

Capacitorのプラグイン機構 Capacitorの場合、プラグインを使ってWebViewからネイティブ機能を呼べる Web

Slide 15

Slide 15 text

自作のブリッジ機構 自作の機構では、まず React Native 側で公開したい関数を書く React Native 型をexportしておくのがミソ

Slide 16

Slide 16 text

自作のブリッジ機構 関数群をwrapしたメッセージハンドラをWebViewに渡す React Native

Slide 17

Slide 17 text

自作のブリッジ機構 Web側から関数をそのままのシグネチャで呼べる 裏でメッセージングが行われてReact Native側で処理が走る(=RPC) Web React Native側でexportした 型だけをimport ⁨⁩全く同じシグネチャで呼び出し

Slide 18

Slide 18 text

仕組み:Comlink Web Workersの関数・オブジェクトをメインスレッドから透過的に扱うライブラリ https://github.com/GoogleChromeLabs/comlink

Slide 19

Slide 19 text

仕組み:WebWorkerとWebViewのアナロジー Comlink は postMessage によるメッセージングを隠蔽する → WebViewもメッセージングできるので応用可能 ブラウザ メインスレッド Web Worker postMessage postMessage WebView React Native postMessage injectJavaScript App→WebはJS埋め込みで 無理やりメッセージを送る

Slide 20

Slide 20 text

JavaScript/TypeScriptで書けることのすごさ JavaScriptという標準化された規格に乗っているからこそ、 Webの豊富なエコシステムを応用できる TypeScriptで揃っているからこそ、シンプルな仕組みでRPCができる これはReact Nativeにしかできないこと

Slide 21

Slide 21 text

宣伝:react-native-webview-rpc OSSなのでぜひ使ってください ~300行程度なので読んでみてください https://github.com/yukukotani/react-native-webview-rpc

Slide 22

Slide 22 text

Web版をモバイルアプリ向けにビルド

Slide 23

Slide 23 text

おさらい:構成 Web向け ビルド Mobile App向け ビルド Expo (React Native) Web Browser アクセス ビルド ビルド Next.js 自作のブリッジ でネイティブ機能呼び出し 一部画面のみ WebViewでアクセス ・既存のWebアプリをモバイルアプリ向けにビルドし、別ドメインで配信 ・WebViewからブリッジ(RPC)でReact Nativeの関数を呼び出し

Slide 24

Slide 24 text

環境変数でWeb/モバイルアプリの処理を分岐 例)ネイティブAPI呼び出し、UI出し分け ネイティブAPI (RPC)とWeb APIを呼び分ける例

Slide 25

Slide 25 text

ビルド時点で環境変数を注入 Tree ShakingやDead Code Eliminationで別環境向けのコードは消える →Web版のバンドルサイズ等に影響を与えずにモバイルアプリ向け拡張ができる

Slide 26

Slide 26 text

その他

Slide 27

Slide 27 text

その他 話しきれないので懇親会で話しましょ@ WebViewへの認証情報引き継d 逆にリニューアル前のアプリのWebViewからのクレデンシャル引き継d WebViewスタック積みまくると重い問t DeepLinkとWebViewの関係Æ Magicpodとの連携

Slide 28

Slide 28 text

Thanks!