[React Native] プロジェクトの基本構成を確認する

モバイルアプリのクロスプラットフォームフレームワーク「React Native」はどのような作りでクロスプラットフォームを実現しているか、プロジェクト構成をざっくり確認してみました。
2018.09.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

React Nativeのプロジェクトの基本構成を確認しよう

React Native は、Facebook社が開発・公開しているネイティブアプリのクロスプラットフォーム開発フレームワークです。言語としてJavaScriptを使用し、React.jsを触ったことがある人であれば気軽にモバイルアプリ開発を始められます。

先日紹介した下記の記事では create-react-native-app というツールを使って、React Nativeのサンプルプロジェクトをサクッと生成しました。

【お試し10分】React Nativeことはじめ!サンプルアプリをサクッと動かす

本記事では基礎を学ぶため、React Nativeのプロジェクト構成を確認していきたいと思います。React Nativeがどのような仕組みでクロスプラットフォームで実行できるようになるかを知るためには構成について理解を深めていく必要がありますが、まずはその取っ掛かりとして、どのようなファイル・フォルダ構成になっているかを確認してみます。

検証環境

以下の環境で試しました。

  • macOS High Sierra 10.13.2
  • Node.js 9.8.0
  • yarn 1.7.0
  • React 16.3.1
  • React Native 0.55.2
  • Xcode 9.0

create-react-native-app のプロジェクトは簡単に試せるよう、シンプルにまとめられている

まずはじめに知っておきたいのが、以前記事で紹介した create-react-native-app で生成されるプロジェクトは、構成がシンプルになるよう、必要なソースコードの一部のみが編集可能な状態になっているということです。ちなみに以下のような構成になっています。

.
├── .babelrc
├── .expo
├── .gitignore
├── .watchmanconfig
├── App.js
├── App.test.js
├── README.md
├── app.json
├── node_modules
├── package.json
└── yarn.lock

また、Expoという簡単に実機デバッグができるツールも導入されているため、素のReact Nativeかと言われると、実は少しだけオプション機能が含まれている状態になっています。

Ejectしてみる

create-react-native-app のプロジェクトは、シンプルな構成を取り外す(Eject)する機能があります。Ejectすることで、通常のReact Nativeのプロジェクト構成に戻すことができます。Reactの世界にも簡単に試せるツールとして create-react-app があり、同様にEjectという機能があります。Reactを知っている人は馴染みがあるかも知れません。

方法はこちらに記載されています。

$ yarn run eject

eject を実行すると、次のようなメッセージが表示されます。

yarn run v1.7.0
$ react-native-scripts eject

We didn't find any uses of the Expo SDK in your project, so you should be fine to eject to
"Plain" React Native. (This check isn't very sophisticated, though.)

We strongly recommend that you read this document before you proceed:
  https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md

Ejecting is permanent! Please be careful with your selection.

? How would you like to eject from create-react-native-app?
❯ React Native: I'd like a regular React Native project.
  ExpoKit: I'll create or log in with an Expo account to use React Native and the Expo SDK.
  Cancel: I'll continue with my current project structure.

Expoを外した状態のReact Nativeプロジェクトか、Expoを付属した状態のReact Nativeプロジェクトか選べます。今回は React Native を選択します。

Writing your selections to app.json...
Wrote to app.json, please update it manually in the future.
Scanning folders for symlinks in /Users/yuki/work/AwesomeProject/node_modules (21ms)
Generating the iOS folder.
Generating the Android folder.
Successfully copied template native code.
Babel preset changed to `babel-preset-react-native-stage-0/decorator-support`.
Updating your yarn scripts in package.json...
Your package.json is up to date!
Adding entry point...
Added new entry points!

【中略】

Ejected successfully!
Please consider letting us know why you ejected in this survey:
  https://goo.gl/forms/iD6pl218r7fn9N0d2
Done in 380.46s.

このような構成になりました。

.
├── .babelrc
├── .expo
├── .gitignore
├── .watchmanconfig
├── App.js
├── App.test.js
├── README.md
├── android
├── app.json
├── index.js
├── ios
├── node_modules
├── package.json
└── yarn.lock

それぞれのファイル・ディレクトリは次のような役割があります。

ファイル・ディレクトリ名 役割
README.md プロジェクトの概要
index.js React Nativeアプリの起動ファイル
App.js React Nativeアプリの起動画面のクラス
App.test.js App.js のテスト
app.json React Nativeアプリの設定
package.json Nodeプロジェクトの設定(スクリプトの定義、依存Moduleの設定など)
yarn.lock Nodeプロジェクトの依存Moduleのロックファイル
node_modules/ React Nativeに依存Moduleのソースコード
android/ Androidのアプリプロジェクト
ios/ iOSのアプリプロジェクト
.babelrc Babelの設定
.expo Expoの設定
.gitignore Gitから除外するファイル・ディレクトリの設定
.watchmanconfig ファイル監視ツール「watchman」の設定

index.js がReact Nativeの起動ファイルになっています。このファイルの中を覗いてみると、App.js に記述されている App クラスを登録していることが分かります。

import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('AwesomeProject', () => App);

React Nativeのプロジェクト構成も確認してみる

ここまで create-react-native-app で素のReact Nativeのプロジェクト構成を確認してみます。次のチュートリアルを参考に、まずは環境を整えます。

まず react-native-cli をインストール。

$ yarn global add react-native-cli

そして react-native-cli を使ってプロジェクトを作ります。AwesomeNativeProject としました。

$ react-native init AwesomeNativeProject
$ cd AwesomeNativeProject

こんな感じの構成になりました。設定ファイル以外は、全く同じですね。

.
├── .babelrc
├── .buckconfig
├── .flowconfig
├── .gitattributes
├── .gitignore
├── .watchmanconfig
├── App.js
├── android
├── app.json
├── index.js
├── ios
├── node_modules
├── package.json
└── yarn.lock

まとめ

React Nativeプロジェクトの構成を見ることで、どのような作りでクロスプラットフォームを実現しているか少し理解できました。