React NativeのAndroid実行時にハマったエラーが結構しんどかったので記事にまとめることにしました。 今回のエラーはLinuxだとハマる沼なので他のOSだと分かりませんのでご了承ください。
実行環境: Ubuntu 16.04.5 LTS, Android 8.1.0
#JavaScriptファイルがbundleされなかった
React NativeはReactというJavaScriptライブラリを使ってNativeアプリ(スマホアプリ)を作ることができる便利なフレームワークです。
今回ハマったエラーはJavaScriptファイルがbundleされていないというエラーです。 bundleされていないというのは複数のJavaScriptファイルが1つのファイルにまとめられていないという意味です。 以下が該当のエラーです。
unable to load script from assets index.android.bundle
#一般的なエラーの対処法
- 開発サーバーのtcpポート番号とデバイスのtcpポート番号を揃える
$ adb reverse tcp:8081 tcp:8081
$ react-native run-android
これは実機で開発している時の話ですが、開発サーバー(PC)とデバイス(スマホ)のtcpポート番号が違うとbundleが上手くいかないそうなので、まずこれを試してみました。 自分の場合はこれでは治らなかったので原因は別にあるようです。
- JavaScriptファイルを自分でbundleする
$ midir android/app/src/main/assets/
$ react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
$ react-native run-android
bundle自体が上手く行ってないと考えたので、react-native bundleというJavaScriptファイルを自分でbundleをするコマンドを以下を参考にして実行しました。
https://stackoverflow.com/questions/44446523/unable-to-load-script-from-assets-index-android-bundle-on-windows
しかし、以下のようなエラーが出ました。
Loading dependency graph...fs.js:1384
throw error;
^
Error: watch /* アプリのどこかしらのファイルのパス */
ENOSPC
ENOSPCというエラーメッセージが出てますが、これが重要でした。
##ENOSPCとは
ENOSPCとはディスクに空きスペースがない時に起こるエラーです。しかし、Ubuntuではディスクに空きスペースがあってもこのエラーが起きることがあります。 それにはinotifyというLinuxのファイル監視用システムが影響しています。 inotifyが監視できるファイル数には上限があり、それを超えてしまった時同様にENOSPCを出します。
react nativeにはwatchmanという、コードの変化を発見して、自動でコンパイルしデバイスに更新を反映させるシステムがあります。 watchmanはファイルの監視にinotifyを用いており、これがENOSPCの原因になったと考えられます。
#ENOSPCへの対処法
先述した通りinotifyの監視ファイル数の上限に達したのがエラーの原因なので、上限を増やしてあげれば大丈夫です。 以下のコマンドを実行すれば上限を増やすことができます。
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
現在のinotifyの監視ファイル数の上限は以下のコマンドで確認できます。
$ cat /proc/sys/fs/inotify/max_user_watches
同じ内容は以下のリンク先に書いてあります。
https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers
$ react-native run-android
を実行したら上手くいきました!
#まとめ
unable to load script from assets index.android.bundle
というエラーが出た時はぜひ参考にしてください。