ReactNativeバージョンアップ作業は新規プロジェクトに移植方式が良い (v0.48.4 -> v0.60.5)

2年ぶりにiOSアプリのReact Nativeのバージョンアップ作業を行いました。v0.48.4 -> v0.60.5。バージョンをひとつ上げるだけでも苦しめられていたのに、これだけ大幅なバージョンアップは気が遠くなる苦行に違いありません。だけど、Google アナリティクス開発者サービス SDK が終わってしまうため、他のアクセス解析を導入する必要があります。

この困難な道のりを出来るだけ平坦にする良い方法はないか模索してみました。そして、既存プロジェクトのReactNativeバージョンを上げてエラーと格闘するよりも、最新のReactNativeで新規プロジェクトを作成し、そこにソースコードを移植する方が簡単ではないかという結論になりました。実際どうなのかは不明ですが、この新規プロジェクト立ち上げ方式に託してみることに。

react-native init NewProject
cd NewProject
npm install
react-native run-ios

新規プロジェクトはまぁ普通に動いたので、とりあえず使いたいモジュールをpackage.jsonに追加してみました。すると、ReactNative v0.60から追加されたautolinkなるものが非常に便利でした。package.jsonにモジュールを追加してnpm installした後にpod installすると、Xcodeプロジェクトへの追加やバイナリのinclude設定などを自動的にしてくれます。autolink以前はXcodeのモジュール設定でうまく行かずclean&buildを繰り返していた記憶があるので、この作業時間がなくなるのは素晴らしいです。モジュールを削除してからnpm installすればちゃんとXcodeからも削除もしてくれます。

ただし、autolink未対応のモジュールや古いモジュールについては、対応されるまで待つか、以前のように手動でXcodeに追加する必要があります。手動追加する場合は、プロジェクト直下にreact-native.config.jsというファイルを作って以下の記載をすることで、指定したモジュールのautolinkを動かなくしておきます

module.exports = {
   dependencies: {
    'realm': {
      platforms: {
      ios: null,
      },
    },
  },
}

使っているモジュールのうち、realmのみこの手動追加が必要でした。realmについてはautolink対応がissuesに上がっているので、対応されるまで待つ必要がありそうです。

realm動作確認用の簡易ソース

import React from 'react'
import { Text } from 'react-native'
import Realm from 'realm'
const ExampleComponent = (props) => {
    return ( Hello world!)
}
export default class App extends React.Component {
  render() {
    let realm = Common.getRealm()
    return (
         
    );
  }
}

React Navigationアップデート

というわけで、まずはrealmが動く状態にしてから、既存プロジェクトからappディレクトリ、index.jsなどをコピーして再びrun-ios。そして、React Navigationのバージョンを上げないとダメっぽいので最新版に。更に、いくつかのエラーに対応しました。

エラー「unable to raesolve module reactnative-gesture-handler」-> いくつかのモジュールがスピンアウトしたらしく、Getting started · React Navigationを参照してインストールしたらOK。

エラー「bundling failed: Error: Unable to resolve module `./navigators/createContainedStackNavigator」-> キャッシュクリアで解消

npm start --reset-cache

エラー「undefined is not a function (evaluating '(0,_reactNavigation.stacknavigator)’)」-> StackNavigatorが消滅してCreateStackNavigatorになっていたので修正。更に、同じような感じで以下の関数を修正。
TabNavigator -> createBottomTabNavigator
StackNavigator -> createStackNavigator

エラー「Loading dependency graph…jest-haste-map: Haste module naming collision: react-native
The following files share their name; please adjust your hasteImpl:
* /node_modules/react-native/package.json
* /ios/Pods/React/package.json」
-> どうも古いプロジェクトで使っていたios/Pods/React/package.jsonがゴミとして悪影響を与えていたっぽい。Podsディレクトリを削除してからpod installしたらOK。

addNavigationHelpersが消滅していたので修正。

無事?アップデート完了

色々修正したりしましたが、事前に想像していたよりも作業がサクサク進んだ気がします。もっと死ぬかと思ってた。すべてをクリアして一からやり直す下記コマンドはそんなに何度も使うことなくエミュレータ動作確認まで漕ぎ着けることができました。

rm -r node_modules && npm i && cd ios && pod install && cd .. && react-native run-ios

未分類

Posted by kabueye