reactnative

"react-native link" は何をするか

More than 1 year has passed since last update.

はじめに

ReactNative で、 npm モジュールを利用する場合、次のように react-native link コマンドを実行する必要がある場合と、ない場合があります。link は一体なにをやっているのでしょうか?

# link が不要
$react-native install hoge --save

# link が必要
$react-native install hoge --save
$react-native link hoge

link が必要な場合

link がどんな場合に必要なのかは、 ReactNative の LinkingLibraries に記載されています。

All the libraries we ship with React Native live on the Libraries folder in the root of the
repository. Some of them are pure JavaScript, and you only need to require it. Other libraries
also rely on some native code, in that case you'll have to add these files to your app, otherwise
the app will throw an error as soon as you try to use the library.

つまり、Javascript オンリーのモジュールを利用する場合には link は不要だけど、NativeCode を利用する場合には必要ということです。この NativeCode を利用する場合に必要、というのが若干の曲者で、単に Objective-C や、Java で書く必要性がある場合だけでなく、追加するファイルが必要な場合や、Info.plist(iOSのプロジェクト), Gradleファイル(Androidのプロジェクト)を変更する場合も必要です。

link とは

link は、XCode / Android Studio のプロジェクトに対して、 npm モジュールが、 XCode / AndroidStudio のプロジェクトファイルに対して必要な変更を、 自動 で代わりに行ってくれるコマンドです。
自動で代わりに行ってくれるだけなので、手動 で行うこともできます。しかし、たいてい次に記述するように
react-native link コマンドを実行する場合が多いと思うので、よほどのことがなければ、 link コマンドを使った方が良いとおもいます。

link hoge vs link

// package.json に記載されている module すべてを link する
$ react-native link

// hoge module を link する
$ react-native link hoge

ファイルの追加について

XCode(iOSアプリ用)の プロジェクトと、 AndroidStudio(Androidアプリ用)の プロジェクトはファイルの管理方法が異なります。

XCode

  • ファイルの場所を、 XCode が管理
  • ディレクトリにファイルを追加しただけでは、XCode はそのファイルを認識しません

XCode補足

  • XCodeには、ファイルの管理として、 GroupReference と、FolderReference の2種類あります。 FolderReferenceを作成済みで、その FolderReference にファイルを追加するのであれば、XCode はそのファイルを認識することができます
  • ここでいう、XCodeがファイルを認識する、という意味は、ソースコードであれば、 Build の対象になったり、リソースファイルであれば、アプリのバイナリにそのファイルが含まれる対象になるという意味です
  • XCodeのProjectファイルツリーと、BuildPhases の内容は、連動しているので、正常にファイルが追加されれば、 Build Phases から確認することができます

AndroidStudio

  • 適切なディレクトリに追加するだけで、AndroidStudio はそのファイルを認識します

事例1 フォントの変更

ReactNative で カスタムフォントを使用する
- ファイルの追加
- XCodeProject ファイルの変更
- Info.plist の変更(iOSアプリ開発で、カスタムフォントを利用するには、Info.plist の変更が必要)

事例2

react-native-vector-icons

npm install

$npm install react-native-vector-icons --save
+ react-native-vector-icons@4.4.2
updated 1 package in 4.796s

$git status
On branch master
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:   package-lock.json
    modified:   package.json

変更点

  • package.json
  • package-lock.json
  • node_modules (.gitignoreされているので、git status には表示されない)

link

$ react-native link react-native-vector-icons
Scanning folders for symlinks in /Users/hino/Documents/1gn/react/react_native/RNSample/node_modules (17ms)
rnpm-install info Linking react-native-vector-icons android dependency
rnpm-install info Android module react-native-vector-icons has been successfully linked
rnpm-install info Linking react-native-vector-icons ios dependency
rnpm-install info iOS module react-native-vector-icons has been successfully linked
rnpm-install info Linking assets to ios project
rnpm-install WARN ERRGROUP Group 'Resources' does not exist in your Xcode project. We have created it automatically for you.
rnpm-install info Linking assets to android project
rnpm-install info Assets have been successfully linked to your project
$git status
On branch master
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:   android/app/build.gradle
    modified:   android/app/src/main/java/com/rnsample/MainApplication.java
    modified:   android/settings.gradle
    modified:   ios/RNSample.xcodeproj/project.pbxproj
    modified:   ios/RNSample/Info.plist

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

    android/app/src/main/assets/

XCodeProjectに対する変更

  • ios/RNSample.xcodeproj/project.pbxproj

    • node_modules/react-native-vector-icons/Fonts 内のファイルを参照として追加
    • XCodeは上述したとおり、ファイルを参照するという方法なので、module の追加でファイルの追加が必要な場合はこのやり方が自然。
    • ReactNativeIcons のバイナリファイルへの参照を追加
  • ios/RNSample/Info.plist
    このアプリの中で、参照されたフォントを使いますよという宣言が追加されている。

+       <key>UIAppFonts</key>
+       <array>
+               <string>Entypo.ttf</string>
+               <string>EvilIcons.ttf</string>
+               <string>Feather.ttf</string>
+               <string>FontAwesome.ttf</string>
+               <string>Foundation.ttf</string>
+               <string>Ionicons.ttf</string>
+               <string>MaterialCommunityIcons.ttf</string>
+               <string>MaterialIcons.ttf</string>
+               <string>Octicons.ttf</string>
+               <string>SimpleLineIcons.ttf</string>
+               <string>Zocial.ttf</string>
+       </array>

AndroidStudioProject に対する変更

  • android/app/build.gradle アプリのbuild に、:react-native-vector-icons というモジュールを加えますよという宣言
+    compile project(':react-native-vector-icons')
  • android/app/src/main/java/com/rnsample/MainApplication.java ReactNative側から、参照するためのソースコード
+            new VectorIconsPackage()
  • settings.gradle

AndroidStudio の Project react-native-vector-icons という AndroidModule を追加するという宣言

- +include ':react-native-vector-icons'
+project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')