今度はTypeScript + React Native for Web + React Navigation + webpack + github pages templateを作ってみました。
こちらにコードはありますのでみてみてね〜
過去のHello World記事
はじまり
RN for webを使ってアプリ作りをしているのですが、React Navigationを使いたくなったので、そのためにHello Worldアプリを作ってみました。
ただ、結構ハマったのでそれを解説したいと思います。結論としては動いたのでよかったですが、ちょっとハックが必要でした。
まず、ベースとなる以下の記事で作成したテンプレを拡張したいと思います!以下、説明するパラメタなどは新たに追加したものに関してです。
React Navigationとは
React Nativeのアプリで画面遷移をしたいときに使えるライブラリです。
これがあると、簡単にNavigationが実装できます。
ただ、一つ問題が。
公式がいうには、React Native for Webでのサポートはバグが多めだよ!とのこと。
でも、一応はサポートしているらしい・・?
なので、公式のHello Worldアプリを使って確かめてみます。
まずは、依存の追加
こちらを参考にしつつ、以下の依存を追加します。
yarn add -D react-native-screens react-native-safe-area-context @react-navigation/native @react-navigation/native-stack
Create a native stack navigatorを実装してデバッグサーバでロードしてみても、あれ、うまくいかない・・
**ERROR** in **./node_modules/react-native/Libraries/Utilities/codegenNativeComponent.js** **13:12**
**Module parse** **failed****:** **Unexpected** **token (13:12)**
**You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders**
**| // TODO: move this file to shims/ReactNative (requires React update and sync)**
**|**
**> import type {HostComponent} from '../../Libraries/Renderer/shims/ReactNativeTypes';**
**|**
**| import requireNativeComponent from '../../Libraries/ReactNative/requireNativeComponent';**
@ ./node_modules/react-native-safe-area-context/lib/module/specs/NativeSafeAreaView.js 1:0-93 2:15-37
@ ./node_modules/react-native-safe-area-context/lib/module/SafeAreaView.js 3:0-60 35:42-60
@ ./node_modules/react-native-safe-area-context/lib/module/index.js 2:0-31 2:0-31
@ ./node_modules/@react-navigation/elements/lib/module/SafeAreaProviderCompat.js 3:0-133 12:48-68 25:4-24 31:34-55 45:42-58 100:42-71
@ ./node_modules/@react-navigation/elements/lib/module/index.js 15:0-77 15:0-77
@ ./node_modules/@react-navigation/native-stack/lib/module/views/NativeStackView.js 1:0-137 10:44-61 11:42-64 26:13-27 48:44-50 60:44-50 61:15-29 76:50-66 119:40-66
@ ./node_modules/@react-navigation/native-stack/lib/module/index.js 9:0-69 9:0-69
@ ./src/App.tsx 1:517-558
@ ./index.web.ts 3:0-28 5:43-46
webpack 5.91.0 compiled with **1 error** in 5209 ms
ログを眺めていると、codegenNativeComponent.jsの中で、Unexpected token のエラーがでています。これは、だいたいがwebpackのloaderが原因なことが多いです。
てか、そもそも/node_modules/react-native/Libraries/Utilities/codegenNativeComponent.js
でエラーが起きているということ自体おかしいです。
webpackの設定で、以下のエイリアス設定をしたため、react-native
のパスはすべてreact-native-web
へ行くはずなのに、react-native
に辿り着いてしまっています。
resolve: {
alias: {
'react-native$': 'react-native-web',
},
extensions: ['.ts', '.js', '.tsx', '.web.ts'],
},
怪しい。。
しかしこれだけが問題ではありませんでした。
試しに、react-native-web
配下にcodegenNativeComponent.js
はあるのか確認してみましたが、ないのです・・
え、じゃあエイリアス解決しても無理じゃね?と思った私。
とはいっても、同じ問題にハマってる人はいるはずだと思い、ググってみました。
見つけた解決策!
予想どおり?同じ問題に当たってる人がちらほらいて、こちらの記事がとても役立ちました。
とりあえず、同じようにwebpack.config.ts
を修正してみたところ、うまく動いたのです。
expo-dev-menuを追加するのがミソ
上記の記事で、ぽろっと書いてあるのですが、どうやら最初に入れた依存 react-native-safe-area-context
が悪さをしているらしいです。
なーるーほーど!
expoとは?
React Nativeの開発用ツール。SDKです。
これがあれば、ビルドやサーバの構築すべてやってくれる超便利ツール!
RN Appを作りたい人にとっては神ツールらしいですね。
なので、expo側のコードは使えるようになっている準備万端なものになっているのです。
こちらには、react-native-safe-area-context
があるようです。これを拝借するということですね。
拝借する
依存を追加します。
yarn add expo-dev-menu expo-modules-core
そのあとに、エイリアスをwebpack.config.ts
に追加します。こうすることで、react-native-safe-area-context
はすべて、expoのものに置き換わります。
'react-native-safe-area-context': 'expo-dev-menu/vendored/react-native-safe-area-context/src',
そして、loaderも正しく適用されるようにします。
path.resolve(__dirname, 'node_modules/expo-dev-menu/vendored/react-native-safe-area-context/src'),
tsconfig.json
にも必要とエラーが出たので追加しておきます。
"include": ["node_modules/expo-dev-menu/vendored/react-native-safe-area-context/src/*"]
またまたエラー・・次はなんだ?
ERROR in /Users/jiji/workspace/ts-wp-rnweb-nav-helloworld/node_modules/expo-dev-menu/vendored/react-native-safe-area-context/src/useWindowDimensions.tsx(32,18)
TS2339: Property 'removeEventListener' does not exist on type 'Dimensions'.
TypeScriptのtypeエラーが出ています。エラーがでているファイルを見に行くと、removeEventListener
を使っていました。
ちなみに、Demensions
というのは、React NativeのAPIなのですが、最近removeEventListener
はdeprecatedになったのです。
なので、RN側の推奨である、addEventListener
した返り値をremove()
するようにすると、エラーが消えてロードできるようになりました。
なのでパッチ応急措置で乗り切りましょう。以下を参考に、パッチを作りました。
サンプル
ロードができたので、そこから簡単にNavigation APIが使えることを確認しました。レイアウトぐずぐずですけど、とりあえず動きます・・!
まとめ
TypeScript + React Native for Web + React Navigation + webpack な環境を作ってみました。
ハマりましたが、なんとか脱出成功です!
にほんブログ村に参加しております!よろしければクリックお願いします 🙂
にほんブログ村
コメント