Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
React Native と WebView を堅実に連携させる
Search
cm-ayf
April 24, 2026
Programming
120
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React Native と WebView を堅実に連携させる
cm-ayf
April 24, 2026
Other Decks in Programming
See All in Programming
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
650
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
270
Press start. Python's next generation.
willingc
PRO
3
300
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
200
in-process GraphQL のすすめ #ginzajs
izumin5210
4
1.5k
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
50
31k
AI時代に学ぶ 好きなルール 嫌いなルール Linter編
shorty5121
0
730
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
370
freee が目指す データ マネジメント戦略 AI-Ready 時代を支える 攻めのガバナンスとは
freee
PRO
0
580
Loosening the Reins: Go Generics Get More Flexible
kuro_kurorrr
0
360
「つくるAI」だけではバグは見つからない ~テストに必要な「見つけるAI」を分離させる戦略~
mfunaki
0
220
VibeCodingからAgenticWorkflowへ
starfish719
0
1.1k
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
77
5.5k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
260
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
640
Believing is Seeing
oripsolob
1
200
sira's awesome portfolio website redesign presentation
elsirapls
0
380
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Making the Leap to Tech Lead
cromwellryan
135
10k
The Limits of Empathy - UXLibs8
cassininazir
1
630
Amusing Abliteration
ianozsvald
1
280
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Accessibility Awareness
sabderemane
1
190
Transcript
©HEARTBEATS Inc.All rights reserved React Native と WebView を 堅実に連携させる
株式会社 HEARTBEATS(旧商号:株式会社 ventus) 岩田風多 (cm-ayf)
©HEARTBEATS Inc.All rights reserved 電子トレカ®コレクションサービス ORICAL® をガワネイティブでストアに配信 • ウェブアプリとして活発に運用されているサービス ◦
御歳6歳のレガシーなコードベース ◦ 20以上あるコンテンツごとに UI をカスタマイズ ◦ Weekly のリリーススケジュール • iOS / Android アプリとして配信したい ◦ ストアで配信したい ◦ アプリ内課金・リワード広告などを実装したい ◦ (昔は React Native で二重実装していた) • ガワネイティブにしよう ◦ WebView で Web アプリを表示 ◦ アプリ側から Web アプリに 安定したインターフェースを提供
©HEARTBEATS Inc.All rights reserved React Native でアプリを実装して WebView と型を共有しながら連携 •
React Native と bridge.js、bridge.js と Web アプリの間で型を共有 ◦ React Native が WebView に注入する bridge.js も型チェック • React Native のツールチェーンで bridge.js もビルド ◦ Babel プラグインで import によってコード文字列を得る ◦ Metro の dev サーバーでちゃんとリロードできる • 実際に Firebase Auth を簡単・安全に連携している ◦ bridge.js から Persistence を提供するだけで連携
©HEARTBEATS Inc.All rights reserved • 環境の境界とリポジトリの境界を別の場所に置いている ◦ 環境の境界は型が安定していない ◦ リポジトリ・リリースの境界は安定したインターフェースが必要
• 下図の全体で1つの型定義を共有することができる React Native と bridge.js、bridge.js と Web アプリの間で型を共有 React Native bridge.js Web アプリ アプリのリポジトリ Web のリポジトリ WebView 上で実行 Hermes で実行 リポジトリ・リリースの境界 (安定したインターフェース ) 環境の境界 (Comlink over postMessage)
©HEARTBEATS Inc.All rights reserved • bridge.js は React Native 内では文字列として扱う
◦ WebView の injectedJavaScript に渡すため ◦ default import で文字列が得られるように Babel でトランスパイルする • Reload on save や *.{ios,android}.js に対応 ◦ import はあくまで Metro が解決するため React Native のツールチェーンで bridge.js もビルド // window.AppBridge を定義 import './bridge'; window.AppBridge.LoggerService .addListener((level, log) => { console[level](log); }); // window.AppBridge を定義 import $1 from './bridge'; export default $1 + `window.AppBridge.LoggerService .addListener((level, log) => { console[level](log); });`; アプリのリポジトリに commit injectedJavaScript に変換
©HEARTBEATS Inc.All rights reserved • Firebase Auth の認証情報ストアを React Native
に委託する ◦ React Native 側と同じ認証情報を参照・永続化 ◦ https://firebase.google.com/docs/auth/web/auth-state-persistence?hl=ja • bridge.js で interface Persistence を実装するクラスを提供 ◦ Web アプリ側では global に生えているクラスを指定するだけ ◦ Comlink だけでは同期的に new Persistence() できない 実際に Firebase Auth を簡単・安全に連携 // bridge.js /** @implements PersistenceInternal */ class ProxiedPersistence { async _isAvailable() { /* call bridge */ } async _get(key) { /* call bridge */ } async _set(key, value) { /* call bridge */ } async _remove(key) { /* call bridge */ } } window.AppBridge.ProxiedPersistence = ProxiedPersistence; // Web アプリ側 if (window.AppBridge?.ProxiedPersistence) { initializeAuth(app, { persistence: window.AppBridge.ProxiedPersistence, }) }
©HEARTBEATS Inc.All rights reserved • これまで:細々と保守してまいりました ◦ 2024年9月リリースから安定して稼働中 ◦ 2025年2月に古い
React Native 製アプリをリプレース • これから:欲しいと言われたらすぐにアプリを提供できます ◦ 2026年3月にも新しいアプリをリリース ◦ 短いリードタイム・少ない工数で新しいアプリをリリースできる これまでとこれから
©HEARTBEATS Inc.All rights reserved • 当アプリの保守・新規アプリリリース等 ◦ https://collection.ultraman-cardgame.com/ など •
別の「普通の」React Native アプリの新規開発・保守 • 採用窓口: https://hrmos.co/pages/heartbeats/jobs/0022059 ↓ • 技術ブログ:https://zenn.dev/p/ventus ◦ 私が全然 React Native じゃない記事を上げてます アプリエンジニアを募集しています!