本文为转载文章, 仅用于自己的知识管理收集, 如果涉及侵权,请联系 suziwen1@gmail.com,会第一时间删除
收集该文章,并非代表本人支持文中观点,只是觉得文章内容容易引起思考,讨论,有它自有的价值转载自: https://engineering.brigad.co/demystifying-react-native-modules-linking-964399ec731b
This article is the sequel to part 1: Clean your iOS setup using Cocoapods. You don’t need to read it before this one, as both articles are complementary. Still, feel free to give it a look as you might find some useful tips.
Why?
Because I’m maintaining react-native-webview, I can see how people need more documentation on “whats”, “whys”, “hows”. Linking native project is one of the biggest pains for developers using react-native libraries and I wish to address it because searching “react native link android” on Google leads you to iOS linking in the official docs and the android part is missing. I’ll try to address the basics behind react-native linking on Android and what to do when things are not working as expected.
Installing a new native dependency
For this article, I use react-native-webview as an example, but keep in mind that this would work for any package that does not have extra linking steps.
Once you found the dependency you need, let’s add it to your project.
Run yarn add react-native-webview
and wait for the install to finish. ⏲️
Once you added a dependency with native code, you also need to link it.
Linking means explaining to the native part of react-native where to find the extra code.
To do that, a simple command has been created: react-native link
😍
So let’s use it: react-native link react-native-webview
Now there are three options:
- Link said it was successful and it is ✅
- Link said it was successful and it is not 😭
- Link failed ❌
Link is a command that tries to edit your native project configuration files. However, it highly depends on string research via patterns, so if you changed your files too much, it might not work.
Let’s make sure that your dependency is linked!
On Android, link edits 3 files, nothing more. 👍
The first file to be edited is settings.gradle
. This file is used by gradle to understand where it can find additional project dependencies.
When you first initialize a project, the file looks like this:
- 1rootProject.name = 'example'
- 2
- 3include ':app'
What link does is it adds two lines after rootProject.name = 'example'
every time you link a new dependency. After a successful link command, it should look like this:
- 1rootProject.name = 'example'
- 2include ':react-native-webview'
- 3project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
- 4
- 5include ':app'
The second file to be edited is app/build.gradle
. (Do not edit the one at the top level of your project)
This file defines what should be used to build your project: SDK versions, build rules and dependencies.
In a clean project, it looks like this. However, we only want to pay attention to these lines:
- 1dependencies {
- 2 implementation fileTree(dir: "libs", include: ["*.jar"])
- 3 implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
- 4 implementation "com.facebook.react:react-native:+" // From node_modules
- 5}
When you run the link command it adds a line to add an extra project dependency:
- 1dependencies {
- 2 implementation project(':react-native-webview')
- 3 implementation fileTree(dir: "libs", include: ["*.jar"])
- 4 implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
- 5 implementation "com.facebook.react:react-native:+" // From node_modules
- 6}
The last file to be edited is app/src/main/java/com/example/MainApplication.java
.
The full clean file is here, but in this file, we want to pay attention to two things. Link edits the imports and the getPackages() method.
Below are the imports before the link command:
- 1package com.example;
- 2
- 3import android.app.Application;
- 4
- 5import com.facebook.react.ReactApplication;
- 6import com.facebook.react.ReactNativeHost;
- 7import com.facebook.react.ReactPackage;
- 8import com.facebook.react.shell.MainReactPackage;
- 9import com.facebook.soloader.SoLoader;
- 10
- 11import java.util.Arrays;
- 12import java.util.List;
Inside the imports, link adds one line corresponding to the library.
- 1package com.example;
- 2
- 3import android.app.Application;
- 4
- 5import com.facebook.react.ReactApplication;
- 6import com.reactnativecommunity.webview.RNCWebViewPackage;
- 7import com.facebook.react.ReactNativeHost;
- 8import com.facebook.react.ReactPackage;
- 9import com.facebook.react.shell.MainReactPackage;
- 10import com.facebook.soloader.SoLoader;
- 11
- 12import java.util.Arrays;
- 13import java.util.List;
💡 If you want to know what name to import, it’s just the path inside the node_modules library below the java folder where you replace the ‘/’ by ‘.’ and add the name of the Package class.
A clean getPackages() method looks like:
- 1
- 2 protected List<ReactPackage> getPackages() {
- 3 return Arrays.<ReactPackage>asList(
- 4 new MainReactPackage()
- 5 );
- 6 }
The link command adds the new package to the list:
(and also breaks indentation…🤷)
- 1
- 2 protected List<ReactPackage> getPackages() {
- 3 return Arrays.<ReactPackage>asList(
- 4 new MainReactPackage(),
- 5 new RNCWebViewPackage()
- 6 );
- 7 }
⚠️ Note for react-native-navigation users: all the modifications made to MainApplication.java usually mess up that last step, so you need to add the package to the list manually.
Congratulations, your dependency is now successfully linked. 🏆
Some final words
So what should you do? Use react-native link? Do everything manually?
Well, that is up to you and what you prefer. I think the most important is to understand why it does what it does, and know what to do when it fails, partially or entirely. Of course, some libraries require extra steps (such as adding extra dependencies or overriding methods).
I still use link most of the time.
A good thing can be to run the link command and check the diffs directly on your git client. 🧐
Thank you for reading 💚
In my upcoming articles, I’ll try to define guidelines for react-native projects that should help you achieve maximum velocity. 💯