Expoはreact-nativeでの開発を楽にするためのラッパーというか開発ツールです。
SDKのバージョンのいくつかから、react-native-webを使ってWebアプリ開発も同時にできるようになりました。
iOS/Androidと同時に、Webも作れてしまうというものです。
ざっと使ってみた感じ、凝ったUIでなければ、重たいけど割とそのまま動いている印象です。
Expo-webはWebViewに非対応
自分の作っているExpoのアプリで、WebViewを使っている部分がありました。下のとおりExpo-webは現時点(SDK41)で、WebViewには非対応です。
そこで、WebViewのほうは変えないまま対応する方法を探したところ react-native-web-webview
というのを発見しました。
react-native-web-webview
を使う方法について書きます。
react-native-web-webview のための設定
このパッケージ自体は適当にググった結果見つけていたのですが、設定のドキュメント読んでも、よくわかりませんでした。
しばらく放置してましたがこのZennの本を参考にようやく実装方法を理解しました。その他全般の理解に役立ったので、ExpoでのWeb対応を考えている方は読むといいかもしれません。
webpack.config.js の生成
まず、やるべきことは、Web向けに独自の設定を入れるために webpack.config.js
ファイルを生成します。以下のコマンドを叩きます。
$expo customize:web
webpack.config.jsの設定
生成された webpack.config.js
に、react-native-web-webviewの設定を追記します。
const createExpoWebpackConfigAsync = require("@expo/webpack-config");
module.exports = async function (env, argv) {
const config = await createExpoWebpackConfigAsync(env, argv);
// Customize the config before returning it.
config.module.rules.push({
test: /postMock.html$/,
use: {
loader: "file-loader",
options: {
name: "[name].[ext]",
},
},
});
config.resolve.alias = {
"react-native": "react-native-web",
"react-native-webview": "react-native-web-webview",
};
return config;
};
これで、yarn web
でwebアプリを起動したときに、ネイティブ部分でWebviewだったところが、iFrameで呼ばれるようになります。
postMessage部分の修正
react-native-webviewでは、アプリ本体とデータをやり取りする際に以下のようにpostMessageで送ります。しかし、Webになると window.ReactNativeWebView
がいません。
window.ReactNativeWebView.postMessage(postObject);
Expo-webでiFrameとして読み込んだ場合は window.parent
にメッセージを送ります。
同じドメインで読み込んでいる場合はサンプルコードの通り、 window.parent.origin
を指定すればいいでしょう。自分の場合は違うドメインのものを読み込んでいたので、別のものを指定しています。
window.parent.postMessage(postObject, 'https://yourdomain.com');
自分の実装では、この2つのパターンはWebViewで呼ばれる側のウェブサーバーで出し分けています。
以上のようなやり方で、Expo-webでWebViewが使えるようになりました。おしまい。