概要
React Nativeの開発でOSSライブラリを使うことは多々あります。 具体的には下記のライブラリを使うときにハマりました。 その際、iOSでは動作するがAndroidだと動作せず色々はまったので備忘録として残します。
開発環境
- React Native Environment Info:
エラー内容
いつもどおり、npmインストールをしてexample通りに実装し、iOSでデバッグと調整をして問題なく表示されたあとに、Androidで動作確認をしようとしました。 すると、赤い画面でエラーが発生して、「あれ?」ってなりました。
TypeError: TypeError: TypeError: undefined is not a function (evaluating 'data.entries()[typeof Symbol === "function" ? Symbol.iterator : "@@iterator"]()')
どっかで参照するときにエラーでてるのか。。。けどiOSのときは何もならなかったのに・・・ と不安になるが、とりあえずDebugger起動して確認するか、ということでCmd+m→デバッガ立ち上げをします。 するとChrome Debuggerが立ち上がり再ロードが走るわけですが、、、ウゴイタ。。。 あ、これ前に見たやつ!、、、つらい。となりました。 原因としては下記の通り、デバッガを使わないときや実機ではiOSやAndroid上のJavascriptCoreScript(JSC)を使ってレンダリングが実行されるが、デバッガを使うとV8というエンジンを用いてレンダリングされるため挙動が異なるという事象です。
対策1(Core-js)を使う
ここからはググり力が必要です。まずエラー内容を素直に調べるとGitHubにIssueがありました。
エラーが出ているpath-jsにentriesをPolyfillしよう、とのこと。 よって、core-jsをnpmインストールし、エントリポイントであるindex.jsにimportします。
$ npm i core-js
import "core-js"
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('hogehoge', () => App);
すると次なるエラーが発生しました。

対策2
同じようにググります。するとライブラリは違えどGithub Issueがありました。
- これはうまく行かなかったです
- このあたりでも議論されています。
- https://github.com/zloirock/core-js/issues/581
- polyfillsすることで既存のMap処理がcore-jsのmapによって潰されちゃったことが原因っぽいです
- 上記理由をうけて、core-jsをごそっと持ってくるのではなく、選択的に持ってくるやり方にします。
また、core-js@3.x.xだとうまくいかず、core-js@2.6.5ならうまくいくという報告があったのでそれをつかってみます
(1)インストール済みライブラリを消して、新しいライブラリを入れる
$ yarn remove core-js && yarn add --dev core-js@2.6.5
(2)polyfill.jsを作成(エントリーポイントであるindex.jsと同じディレクトリ階層に作成)
global.Symbol = require('core-js/es6/symbol');
require('core-js/fn/symbol/iterator');
require('core-js/fn/object/entries');
require('core-js/fn/map');
require('core-js/fn/set');
require('core-js/fn/array/find');
(3)index.jsの最初の行にpolyfills.jsをインポート
import "./polyfills.js";
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('hogehoge', () => App);
上記設定完了後、react-native run-android をしても問題なく動作させることができました。
まとめ
- React NativeではJavascriptCoreScript(JSC)を使ってレンダリングされるためサポートされていないjavascript functionが存在する
- 存在しないfunctionを利用しているライブラリについてはpolyfillsする
- core-jsでpolyfillsするときはライブラリのダウングレードなども試してみる