Help us understand the problem. What is going on with this article?

React Native 0.55.2->0.56.0にアップグレードした作業ログ

More than 1 year has passed since last update.

この記事の内容

  • 仕事で使っているアプリを0.55.2 -> 0.56.0にアップグレードしたので、その際試した方法、ハマった内容などを共有
  • マイグレーションは大変と噂ですが、割と大変

はじめに

  • 公式ガイド: https://facebook.github.io/react-native/docs/upgrading.html
  • リリース内容: https://github.com/facebook/react-native/releases
  • 方法としては
    1. 公式の react-native-git-upgrade を使ってバージョン間の変更を適用する
    2. 指定バージョン間のdiffを見るツール https://github.com/ncuillery/rn-diff/compare/rn-0.55.2...rn-0.56.0 で変更をみつつ自力でマイグレーションする
    3. package.json 書き換えるなり react-native init して差分見るなりしてがんばる
  • などがあります。今回は1をやろうとして3に切り替えましたが、2を見つつ3が一番楽そう
  • 今回の対象プロジェクト は lerna のmonorepoで、multi packege構造だった
  • やること
    • packege.json の react , react-native のバージョンアップ
    • interfaceの変更に伴い build.gradlexxx.xcodeproj.flowconfig なども必要なら書き換える
    • それにより他のライブラリやJSコード、ネイティブコードが動かなくなるので、一つ一つエラーを見て直していく
    • 後は気合

0.56の変更点

  • https://github.com/facebook/react-native/releases から大きいところ
  • 2018/4/4の0.55から816コミット分の変更
  • Babel 7対応
  • Android 26 SDK対応
  • Node 8 がminimum required versionに
  • iOS9 が minimum required versionに
  • Xcode 9 が minimum required versionに
  • 他にも100くらいの変更あるので公式を参照

プロジェクトのディレクトリ構造

色々省略してますが

$ tree -L 2 -I node_modules
.
├── lerna.json
├── package.json
├── packages
│   ├── network
│   ├── domain
│   ├── i18n
│   └── main
├── tsconfig.json
├── tslint.json
├── vendor
│   └── bundle
└── yarn.lock
  • packages/main がメインのアプリケーションのソースコードで、react-nativeに依存しているのはそこだけ
  • packages/main 内にあるpackege.json 内の dependenciesnetwork や domain 等のパッケージへの依存が書かれてます

プロジェクトの事情

  • ReactNative触るのは全員モバイルエンジニア(Mac)
  • React Nativeを一からTypeScriptで開発しているプロジェクトで、git cloneしてきたらとりあえず init.sh 叩く、みたいにしてる
  • init.sh が行なっているのは npm install -> bundle install -> pod install -> tsc build の一連の環境設定の流れ(ほんとはデベロップメントサーバー起動とか色々ある)

react-native-git-upgrade試した

$ yarn global add react-native-git-upgrade
$ cd packages/main
$ react-native-git-upgrade

エラー xxxx(パッケージ名): Not found

lernaの独自パッケージが参照できずにエラー発生

error An unexpected error occurred: "https://registry.yarnpkg.com/xxxx: Not found".
git-upgrade ERR! An error occurred during upgrade:
git-upgrade ERR! Error: Command 'yarn add react-native@0.56.0 react@16.4.1' exited with code 1:
stderr: undefined+ cd ../xxxx
  • react-native-git-upgrade を実行すると reactreact-native パッケージをアップグレードして、同時に公式レポジトリに入っている変更を適用しようとする
  • lernaには対応してないので npm update に失敗するので、mainパッケージのエラーになったdependenciesを消してみる

再度react-native-git-upgrade実行

普通にいくと下記みたいな出力が出る

git-upgrade info Check for updates 
git-upgrade info Using yarn 1.7.0 
git-upgrade info Read package.json files 
git-upgrade info Check declared version 
git-upgrade info Check matching versions 
git-upgrade info Check React peer dependency 
git-upgrade info Check that Git is installed 
git-upgrade info Get information from NPM registry 
git-upgrade info Upgrading to React Native 0.56.0, React 16.4.1 
git-upgrade info Setup temporary working directory 
git-upgrade info Configure Git environment 
git-upgrade info Init Git repository 
git-upgrade info Add all files to commit 
  • conflictが発生
z1Vi_Zy=U>ksq-G_fM)m29;BR$>lFp~S*{+8W;-V<x(&S9j{qRW5YUQ=V&qVCbh(gE
z1LtGy9zHsxDTSaBmKCgK2%rMY$WK9|m-LzMgv@jUVUKukgw!~V#?v<}@9dn>zpOg_
z{-6B_%gK~tgzphw9K=
    at ChildProcess.child.on.code (/Users/username/.config/yarn/global/node_modules/react-native-git-upgrade/cliEntry.js:58:18)
    at emitTwo (events.js:126:13)
    at ChildProcess.emit (events.js:214:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:198:12)
git-upgrade ERR! Restore initial sources
error: Your local changes to the following files would be overwritten by checkout:
    node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj/xcuserdata/username.xcuserdatad/xcschemes/xcschememanagement.plist
    node_modules/react-native/React/React.xcodeproj/xcuserdata/username.xcuserdatad/xcschemes/xcschememanagement.plist
Please commit your changes or stash them before you switch branches.
Aborting
Error: Command 'git checkout project-snapshot' exited with code 1:
stderr: undefinederror: Your local changes to the following files would be overwritten by checkout:
    node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj/xcuserdata/username.xcuserdatad/xcschemes/xcschememanagement.plist
    node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj/xcuserdata/username.xcuserdatad/xcschemes/xcschememanagement.plist
    node_modules/react-native/React/React.xcodeproj/xcuserdata/username.xcuserdatad/xcschemes/xcschememanagement.plist
Please commit your changes or stash them before you switch branches.
Aborting

stdout:
    at ChildProcess.child.on.code (/Users/username/.config/yarn/global/node_modules/react-native-git-upgrade/cliEntry.js:58:18)
    at emitTwo (events.js:126:13)
    at ChildProcess.emit (events.js:214:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:198:12)
  • 全部の出力だとすごい長いので省略してます
  • この出力見てもよく分からないけど、react-nativeの本家の変更がgitのchangesに出てくる
  • コマンドの実行結果はdiffみたいな内容が出力されることもある
  • git status の結果に最新のReact Nativeとの差分(https://github.com/ncuillery/rn-diff/compare/rn-0.55.2...rn-0.56.0 と大体一緒)が出ている
$ git status
On branch feature/rn_migration
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   .babelrc
    modified:   .flowconfig
    modified:   android/app/build.gradle
    modified:   android/app/proguard-rules.pro
    modified:   android/app/src/main/AndroidManifest.xml
    modified:   android/app/src/main/res/mipmap-hdpi/ic_launcher.png
    modified:   android/app/src/main/res/mipmap-mdpi/ic_launcher.png
    modified:   android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
    modified:   android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
    modified:   android/app/src/main/res/values/strings.xml
    modified:   android/app/src/main/res/values/styles.xml
    modified:   android/build.gradle
    modified:   android/gradle.properties
    modified:   android/gradle/wrapper/gradle-wrapper.properties
    modified:   android/settings.gradle
    modified:   app.json
    modified:   package.json
    modified:   yarn.lock

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    .gitattributes
    .gitignore
    .watchmanconfig
    android/app/BUCK
    android/app/src/main/java/com/
    android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
    android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
    android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
    android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
    android/app/src/main/res/mipmap-xxxhdpi/
    android/keystores/
    ios/main-tvOS/
    ios/main-tvOSTests/
    ios/main.xcodeproj/
    ios/main/
    ios/mainTests/

no changes added to commit (use "git add" and/or "git commit -a")
  • 特に取り込むべき変更が見当たらなかったのでpackage.jsonだけ書き換える方針に切り替え(flow typeとか使ってたら .flowconfig など取り入れるべきと思います)
  • git の変更を全て破棄してから下記を変える
-    "react": "16.3.1",
-    "react-native": "0.55.2",
+    "react": "16.4.1",
+    "react-native": "0.56.0",

起動確認

  • init.shで環境整備(npm install, tsc buildなど諸々)し、 react-native run-android などで実機起動する
  • 当然途中で諸々のエラーが発生する

エラー CocoaPodsで"Folly"が見つからないエラー

  • pod install の途中で下記のエラー
[!] CocoaPods could not find compatible versions for pod "Folly":
  In snapshot (Podfile.lock):
    Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)

  In Podfile:
    Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)

None of your spec sources contain a spec satisfying the dependencies: `Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`), Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)`.

You have either:
 * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
 * mistyped the name or version.
 * not added the source repo that hosts the Podspec to your Podfile.

Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.

ios/Podfile.lockios/Pods/ を消して再度 pod install

エラー Could not find com.facebook.react:react-native:0.xx.x.

  • react-native run-android 失敗した
FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all files for configuration ':app:debugCompileClasspath'.
> Could not find com.facebook.react:react-native:0.55.2.
  Searched in the following locations:
      file:/Users/username/Library/Android/sdk/extras/m2repository/com/facebook/react/react-native/0.55.2/react-native-0.55.2.pom
  • build.gradle内で読み込むreact-nativeのバージョンが違う
  • package.jsonのバージョンと合わせる

build.gradleの修正

-implementation "com.facebook.react:react-native:0.55.2"
-implementation "com.facebook.react:react-native:0.56.0"

エラー Cannot find module 'babel-preset-react-native-dotenv'

  • 環境変数の定義に react-native-dotenv を使っているが、実機でテストするとエラーが発生
Loading dependency graph, done.
error: bundling failed: Error: Cannot find module 'babel-preset-react-native-dotenv' from '/Users/username/Desktop/workspace/packages/main'
- If you want to resolve "react-native-dotenv", use "module:react-native-dotenv"
    at Function.module.exports [as sync] (/Users/username/Desktop/workspace/packages/main/node_modules/resolve/lib/sync.js:42:15)

babel-preset-react-native-dotenv moduleが見つからない
https://github.com/zetachang/react-native-dotenv/issues/44

対応方法

  • バージョン 0.2.0 を指定すればOK
  • 当時 react-native-dotenv がv56に対応していなかったので暫定でforkされたrepositoryを参照するよう変更した
  • .babelrcを下記に変更
{
  "presets": ["react-native", "module:react-native-dotenv"]
}
  • package.json修正
-    "react-native-dotenv": "^0.1.1",
+    "react-native-dotenv": "^0.2.0",

エラー babel-preset-react-native のバージョンが低い

Loading dependency graph, done.
error: bundling failed: TypeError: Cannot read property 'bindings' of null
    at Scope.moveBindingTo (/Users/username/Desktop/workspace/packages/main/node_modules/@babel/traverse/lib/scope/index.js:978:13)
    at BlockScoping.updateScopeInfo (/Users/username/Desktop/workspace/packages/main/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:364:17)
    at BlockScoping.run (/Users/username/Desktop/workspace/packages/main/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:330:12)
    at PluginPass.BlockStatementSwitchStatementProgram (/Users/username/Desktop/workspace/packages/main/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:70:24)
    at newFn (/Users/username/Desktop/workspace/packages/main/node_modules/@babel/traverse/lib/visitors.js:237:21)
    at NodePath._call (/Users/username/Desktop/workspace/packages/main/node_modules/@babel/traverse/lib/path/context.js:65:20)
    at NodePath.call (/Users/username/Desktop/workspace/packages/main/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/Users/username/Desktop/workspace/packages/main/node_modules/@babel/traverse/lib/path/context.js:100:12)
    at TraversalContext.visitQueue (/Users/username/Desktop/workspace/packages/main/node_modules/@babel/traverse/lib/context.js:142:16)
"babel-preset-react-native": "^5".

エラー error: bundling failed: Error: Unable to resolve module react-native/Libraries/Renderer/shims/ReactNativePropRegistry

  • 実機実行してJSのロード中に NativeBase のエラー
error: bundling failed: Error: Unable to resolve module `react-native/Libraries/Renderer/shims/ReactNativePropRegistry` from `/Users/username/Desktop/workspace/packages/main/node_modules/native-base/dist/src/Utils/computeProps.js`: Module `react-native/Libraries/Renderer/shims/ReactNativePropRegistry` does not exist in the Haste module map

This might be related to https://github.com/facebook/react-native/issues/4968
To resolve try the following:
  1. Clear watchman watches: `watchman watch-del-all`.
  2. Delete the `node_modules` folder: `rm -rf node_modules && npm install`.
  3. Reset Metro Bundler cache: `rm -rf /tmp/metro-bundler-cache-*` or `npm start -- --reset-cache`.  4. Remove haste cache: `rm -rf /tmp/haste-map-react-native-packager-*`.
    at ModuleResolver.resolveDependency (/Users/username/Desktop/workspace/packages/main/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:167:1306)
    at ResolutionRequest.resolveDependency (/Users/username/Desktop/workspace/packages/main/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:80:16)
    at DependencyGraph.resolveDependency (/Users/username/Desktop/workspace/packages/main/node_modules/metro/src/node-haste/DependencyGraph.js:237:485)
    at Object.resolve (/Users/username/Desktop/workspace/packages/main/node_modules/metro/src/lib/transformHelpers.js:116:25)
    at dependencies.map.result (/Users/username/Desktop/workspace/packages/main/node_modules/metro/src/DeltaBundler/traverseDependencies.js:298:29)
    at Array.map (<anonymous>)
    at resolveDependencies (/Users/username/Desktop/workspace/packages/main/node_modules/metro/src/DeltaBundler/traverseDependencies.js:294:16)
    at /Users/username/Desktop/workspace/packages/main/node_modules/metro/src/DeltaBundler/traverseDependencies.js:159:33
    at Generator.next (<anonymous>)
    at step (/Users/username/Desktop/workspace/packages/main/node_modules/metro/src/DeltaBundler/traverseDependencies.js:239:307)
-    "native-base": "^2.4.1",
+    "native-base": "^2.7.0",

エラー 型定義が変わった

  • TypeScriptを使っている場合、型定義ファイルも更新しなければいけない
  • TextInputのonFocusに引数が増えた
main: src/components/FormItem.tsx(98,76): error TS2554: Expected 1 arguments, but got 0.
main: src/components/FormItem.tsx(117,22): error TS2326: Types of property 'display' are incompatible.
main:   Type 'boolean' is not assignable to type 'undefined'.
  • 型定義に合わせてコードを修正

エラー jestが実行できない

  • テスト対象ファイル全部ビルド失敗
Plugin 0 specified in "project/node_modules/babel-preset-react-native/index.js" provided an invalid property of "default" (While processing preset: "project/node_modules/babel-preset-react-native/index.js")
-    "babel-core": "^6.26.0",
+    "babel-core": "^7.0.0-beta.54",
-    "babel-jest": "22.4.3",
+    "babel-jest": "23.2.0",
-    "jest": "22.4.3",
+    "jest": "23.2.0",
-    "ts-jest": "^22.4.4",
+    "ts-jest": "^23.0.0",

  "jest": {
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    }
  }

エラー jest で setTimeoutが動かない?

TypeError: Cannot read property 'debug' of undefined
    at /Users/username/Desktop/workspace/packages/main/dist/data/HogeLib.js:26:44
    at Timeout._onTimeout (/Users/username/Desktop/workspace/packages/main/dist/data/__test__/HogeLib.test.js:27:13)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5)
Jest did not exit one second after the test run has completed.
  • 上記からtestが動かない現象、もしくはこれも出ないで永遠にyarn testが終わらない現象が起きました
  • テストコードから不要なsetTimeoutを除去したら起こらなくなりました

エラー Androidのlintが通らない

/Users/username/Desktop/workspace/packages/main/android/app/build/intermediates/res/merged/release/drawable-xhdpi/assets_img_ic_ic.png: error: uncompiled PNG file passed as argument. Must be compiled first into .flat file..

uncompiled PNG file passed as argument. Must be compiled first into .flat file

エラー AndroidのReleaseビルドが通らない

verifyReleaseResources/home/circleci/.gradle/caches/transforms-1/files-1.1/appcompat-v7-26.1.0.aar/0af13b712ba9e9b567dee09bc2b2f546/res/values-v26/values-v26.xml:13:5-16:13:AAPT: No resource found that matches the given name: attr 'android:keyboardNavigationCluster'
  • 使っているネイティブライブラリがAndroid SDK 26に対応していない
  • react-native-navigation など四つぐらいあって、各レポジトリにPRやissueが上がっていた
  • うちのテックリードがライブラリプロジェクトのSDKバージョンを書き換えるgradle task書いてくれた。超感謝
+ext {
+    compileSdkVersion = 27
+    targetSdkVersion = 27
+}
+
+subprojects {
+    afterEvaluate { project ->
+        if (project.hasProperty("android")) {
+            android {
+                compileSdkVersion rootProject.ext.compileSdkVersion
+            }
+        }
+    }
+}

CircleCI落ちた

ipa作成時

[23:53:47]: ▸ ❌  ld: could not reparse object file in bitcode bundle: 'Invalid bitcode version (Producer: '902.0.39.2_0' Reader: '900.0.39.2_0')', using libLTO version 'LLVM version 9.0.0, (clang-900.0.39.2)' for architecture arm64
[23:53:47]: ▸ ❌  clang: error: linker command failed with exit code 1 (use -v to see invocation)
[23:53:47]: ▸ ** ARCHIVE FAILED **

ビルド後、JSロード時に失敗する

lerna ERR! Unable to resolve module `../utils/mapPropsToStyleNames` from `/Users/username/project/packages/main/node_modules/native-base/dist/src/basic/Text.js`: The module `../utils/mapPropsToStyleNames` could not be found from `/Users/username/project/packages/main/node_modules/native-base/dist/src/basic/Text.js`. Indeed, none of these files exist:
  • キャッシュが原因だった
  • よく分からないとこでmodule読み込めないよって言われる
  • node_modules と TypeScriptビルドしたコードを削除したら動く

iOSがリロードでクラッシュ

  • react-native-navigation のバージョンが古い
Fatal Exception: NSInvalidArgumentException
0  CoreFoundation                 0x1124771ce (Missing)
1  libobjc.A.dylib                0x1108ec031 objc_exception_throw
2  CoreFoundation                 0x1124f8784 (Missing)
3  UIKit                          0x10e97f6db (Missing)
4  CoreFoundation                 0x1123f9898 (Missing)
5  CoreFoundation                 0x1123f9278 (Missing)
6  app                       0x10b247421 -[RCCViewController sendGlobalScreenEvent:endTimestampString:shouldReset:] (RCCViewController.m:225)
7  app                       0x10b2480f9 -[RCCViewController viewDidDisappear:] (RCCViewController.m:293)

参考リンク

ここら辺読んでからやりました。感謝
https://qiita.com/ponnjinnka/items/b1fdd200b1bc094c6797
https://qiita.com/hotchpotch/items/5617caccd8749f410631

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away