【Hello World】TypeScript + React Native for Web + React Navigation + Webpack

e-hello-world-nav プログラミング

※当ブログでは商品・サービスのリンク先にプロモーションを含みます。ご了承ください。

今度はTypeScript + React Native for Web + React Navigation + webpack + github pages templateを作ってみました。

こちらにコードはありますのでみてみてね〜

GitHub - jiji-thecat/ts-webpack-rn-hello-world
Contribute to jiji-thecat/ts-webpack-rn-hello-world development by creating an account on GitHub.

過去のHello World記事

はじまり

RN for webを使ってアプリ作りをしているのですが、React Navigationを使いたくなったので、そのためにHello Worldアプリを作ってみました。

ただ、結構ハマったのでそれを解説したいと思います。結論としては動いたのでよかったですが、ちょっとハックが必要でした。

まず、ベースとなる以下の記事で作成したテンプレを拡張したいと思います!以下、説明するパラメタなどは新たに追加したものに関してです。

React Navigationとは

React Navigation | React Navigation
Routing and navigation for your React Native apps

React Nativeのアプリで画面遷移をしたいときに使えるライブラリです。

これがあると、簡単にNavigationが実装できます。

ただ、一つ問題が。

公式がいうには、React Native for Webでのサポートはバグが多めだよ!とのこと。

Support for web is experimental and a work in progress. It has bugs, is missing many features and the API for web integration may change in minor versions. Please help us test it and open bug reports if you encounter a bug.

React Navigation on the Web | React Navigation
Support for web is experimental and a work in progress. It has bugs, is missing many features and the API for web integr...

でも、一応はサポートしているらしい・・?

なので、公式のHello Worldアプリを使って確かめてみます。

まずは、依存の追加

Hello React Navigation | React Navigation
In a web browser, you can link to different pages using an anchor (``) tag. When the user clicks on a link, the URL is p...

こちらを参考にしつつ、以下の依存を追加します。

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 が悪さをしているらしいです。

RN for webはまだ開発中なので、react-native-safe-area-contextを必要とするNavigationはサポートしていない。

なので、expo用のパッケージを拝借するのである。

なーるーほーど!

expoとは?

Expo
Expo is an open-source platform for making universal native apps for Android, iOS, and the web with JavaScript and React...

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を使っていました。

expo/packages/expo-dev-menu/vendored/react-native-safe-area-context/src/useWindowDimensions.tsx at 8ceea398fb1a13ef70ea736f69fc9f61b15db3ff · expo/expo
An open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web. - expo/exp...

ちなみに、Demensionsというのは、React NativeのAPIなのですが、最近removeEventListenerはdeprecatedになったのです。

なので、RN側の推奨である、addEventListenerした返り値をremove()するようにすると、エラーが消えてロードできるようになりました。

なのでパッチ応急措置で乗り切りましょう。以下を参考に、パッチを作りました。

React Nativeのライブラリをpatch-packageで手軽に修正する方法
はじめに あけましておめでとうございます。React Nativeでアプリの開発を行っているとき、なんらかの外部のライブラリ(パッケージ)を使用することが多いかと思いますが、私が開発する上で困ったのがライブラリの特定の機 ...

サンプル

ロードができたので、そこから簡単にNavigation APIが使えることを確認しました。レイアウトぐずぐずですけど、とりあえず動きます・・!

https://jiji-thecat.github.io/ts-webpack-rn-hello-world

まとめ

TypeScript + React Native for Web + React Navigation + webpack な環境を作ってみました。

ハマりましたが、なんとか脱出成功です!

にほんブログ村に参加しております!よろしければクリックお願いします 🙂

にほんブログ村 IT技術ブログへ
にほんブログ村

コメント

タイトルとURLをコピーしました