Expoとは
ExpoはReact Nativeアプリの開発を支援してくれるサービスです。
ビルドや実行環境が提供され、リリース後のアプリでもApple審査なしに変更がリアルタイムに反映され、Webのような感覚で開発ができるのが大きな特徴です。
リリース後にアプリ挙動を外部で変更することを嫌っている Apple社がこれを許している理屈はよくわからないのですが、とにかく現状、問題視されていないのは事実のようです。
もし、今後、問題視されるようになったとしても、クリーンな React Native アプリとの互換性は100%に近いので移行も容易ではないかと思います。恐れずに使って、メリットを享受するというのも一つの考えかと思います。
ちなみに本文にありますが、若干、Expo対応のコードが必要だったりするようです。ネイティブライブラリの制限もある(どういうことが制限となるのか、自分はよく分かってません)ようですので、その辺りを許容できるかが、採用のポイントかなと思います。
開発環境構築
Expo-CLIのインストール
Expoのコマンド群をグローバルにインストールします。
$ npm install expo-cli --g
アプリ作成
プロジェクト作成
Expoのプロジェクトを作成します。
$ expo init [プロジェクト名]
テンプレートの選択
blank と tabs が選べる。ここではblankを選択。
? Choose a template: expo-template-blank
Yarn を使う?
npm ではなくYarnを使うかどうか聞かれてると思う。ここではNoを選択。
? Yarn v1.7.0 found. Use Yarn to install dependencies? No
$ expo start
次のようなコマンドライン表示と、 Metro Bundler (Webページ)が起動します。
「 Press a for Android emulator, or i for iOS simulator.」とあり、「a」押下でAndroidエミュレータ、「i」押下でiPhoneエミュレータでの確認ができます。
iOS
Android
NativeBase、React Navigation を使ってみる
それではアプリ作成をイメージしながら下記で行なったようにNativeBase、React Navigation を使用してみます。
【React Native】NativeBase導入
【React Native】React Navigation を使ってみる(画面遷移編)
上記を参考にインストールしたところ、まず、
$ react-native link
はエラーが出ますが、そもそも、この手順は、Expoの場合は必要ないようです。
更に「expo start」すると、
Unable to resolve "@expo/vector-icons/FontAwesome5" from "node_modules/native-base/dist/src/basic/IconNB.js"
というエラーとなりました。
調べてみたところ、Expo-CLI は Create React Native App をベースにしていて、ちょっと違う手順となるようです。
参考:
https://github.com/GeekyAnts/NativeBase#4-getting-started
以下のインストールを別途行ったところ、iOSエミュレータで「【React Native】React Navigation を使ってみる(画面遷移編) 」と同様の表示、動作が確認できました。
npm install @expo/vector-icons --save
Androidでの問題
iOS では動作が確認できたのですが、Android ではまだ問題が残っていました。
Androidエミュレータ起動すると、
fontFamily 'Roboto_medium' is not a system font and has not been loaded through Exponent.Font.loadAsync.
というエラーとなりました。
NativeBaseでのRoboto_mediumフォントの読み込みに関するErrorについて
を参考に(カスタムフォントがロードされるまでは表示をしないという対処でしょうか)、下記のソース
App.js
import React, {Component} from 'react';
import { createStackNavigator, createAppContainer } from 'react-navigation'
import Main from './screens/Main'
import Push from './screens/Push'
import Modal from './screens/Modal'
const MainNavigation = createStackNavigator(
{
Main: { screen: Main },
Push: { screen: Push },
},
{initialRouteName: 'Main', headerMode: 'none'}
)
const NestNavigation = createStackNavigator(
{
MainNavigation: { screen: MainNavigation },
Modal: { screen: Modal },
},
{initialRouteName: 'MainNavigation', mode: 'modal', headerMode: 'none'},
)
const AppContainer = createAppContainer(NestNavigation);
type Props = {};
export default class App extends Component<Props> {
constructor() {
super();
this.state = {
isReady: false
};
}
componentWillMount() {
this.loadFonts();
}
async loadFonts() {
await Expo.Font.loadAsync({
Roboto: require("./node_modules/native-base/Fonts/Roboto.ttf"),
Roboto_medium: require("./node_modules/native-base/Fonts/Roboto_medium.ttf"),
});
this.setState({ isReady: true });
}
render() {
if (!this.state.isReady) {
return <Expo.AppLoading />;
}
return (
<AppContainer
ref = {nav => {this.navigator = nav;}}
/>
);
}
}
更にナビゲーションバーがステータスバーに重なってしまう問題もあり、app.json に以下の設定の追加が必要でした。
app.json
"androidStatusBarColor": "#334393",
"androidStatusBar": {
"barStyle": "light-content",
"backgroundColor": "#334393" }
}
参考:
https://github.com/expo/expo/issues/71
リポジトリ
本記事で作成したものは以下で公開していますので、参考にしてください。
https://github.com/k-neo/ReactNativeCourseExpo
最後に
本記事はローラハウス が執筆している React Native の記事を集約した【全てのアプリ開発者に贈る】React Native いろいろ触ってみた【目次】 の子記事です。React Native の開発で参考になる情報がきっとありますので、ぜひ他の記事も読んでみてください!