Skip to content

Commit 0a03617

Browse files
authored
fix(bridge): improve missing native module error (#5)
1 parent 5971ff6 commit 0a03617

File tree

7 files changed

+2593
-300
lines changed

7 files changed

+2593
-300
lines changed

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,62 @@ Please note, if you are choosing to not use a dependency manager, you must keep
170170
```
171171

172172
6. `pod install`
173+
174+
### "Failed to load [...] native module"
175+
176+
If you're getting a `Failed to load [...] native module` error, it means that some native code hasn't been injected to your native project.
177+
178+
#### iOS
179+
180+
If you're using Cocoapods, check that your `ios/Podfile` file contains the right pods :
181+
182+
- `Failed to load Analytics native module`, look for the core native module:
183+
```ruby
184+
pod 'RNAnalytics', :path => '../node_modules/@segment/analytics-react-native'
185+
```
186+
- `Failed to load [...] integration native module`, look for the integration native module, example with Google Analytics:
187+
```ruby
188+
pod 'RNAnalyticsIntegration-Google-Analytics', :path => '../node_modules/@segment/analytics-react-native-google-analytics'
189+
```
190+
191+
Also check that your `Podfile` is synchronized with your workspace, run `pod install` in your `ios` folder.
192+
193+
If you're not using Cocoapods please check that you followed the [iOS support without CocoaPods](#ios-support-without-cocoapods) instructions carefully.
194+
195+
#### Android
196+
197+
Check that `android/app/src/main/.../MainApplication.java` contains a reference to the native module:
198+
199+
- `Failed to load Analytics native module`, look for the core native module:
200+
201+
```java
202+
import com.segment.analytics.reactnative.core.RNAnalyticsPackage;
203+
204+
// ...
205+
206+
@Override
207+
protected List<ReactPackage> getPackages() {
208+
return Arrays.<ReactPackage>asList(
209+
new MainReactPackage(),
210+
// ...
211+
new RNAnalyticsPackage()
212+
);
213+
}
214+
```
215+
216+
- `Failed to load [...] integration native module`, look for the integration native module, example with Google Analytics:
217+
218+
```java
219+
import com.segment.analytics.reactnative.integration.google.analytics.RNAnalyticsIntegration_Google_AnalyticsPackage;
220+
221+
// ...
222+
223+
@Override
224+
protected List<ReactPackage> getPackages() {
225+
return Arrays.<ReactPackage>asList(
226+
new MainReactPackage(),
227+
// ...
228+
new RNAnalyticsIntegration_Google_AnalyticsPackage()
229+
);
230+
}
231+
```

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
"lint-staged": "^7.2.0",
6969
"npm-run-all": "^4.1.3",
7070
"prettier": "^1.14.2",
71+
"react": "16.6.0-alpha.8af6728",
72+
"react-native": "^0.57.3",
7173
"rimraf": "^2.6.2"
7274
}
7375
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const forceRequire = (): typeof import('../bridge') => {
2+
jest.resetModules()
3+
4+
return require.requireActual('../bridge')
5+
}
6+
7+
it('should throw an error if the core native module is not linked', () => {
8+
jest.setMock('react-native', {
9+
NativeModules: {}
10+
})
11+
12+
expect(forceRequire).toThrow(/Failed to load Analytics native module./)
13+
})
14+
15+
it('should export the core native module', () => {
16+
const RNAnalytics = {}
17+
18+
jest.setMock('react-native', {
19+
NativeModules: { RNAnalytics }
20+
})
21+
22+
expect(forceRequire().default).toBe(RNAnalytics)
23+
})

packages/core/src/bridge.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import { NativeModules } from 'react-native'
22

33
import bridge = NativeModules.RNAnalytics
44

5+
if (!bridge) {
6+
throw new Error('Failed to load Analytics native module.')
7+
}
8+
59
export default bridge
610
export type JsonMap = NativeModules.RNAnalytics.JsonMap
711
export type Bridge = typeof bridge

packages/integrations/src/gen-integrations.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ async function prepareJs({
140140
),
141141
template('index.js', {
142142
nativeModule,
143+
name,
143144
disable_ios: String(ios.disabled || false),
144145
disable_android: String(android.disabled || false)
145146
}),

packages/integrations/template/index.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ var disabled =
66
? '{{disable_android}}' === 'true'
77
: true
88

9-
module.exports = disabled
10-
? { disabled: true }
11-
: ReactNative.NativeModules['{{{nativeModule}}}'].setup
9+
if (disabled) {
10+
module.exports = { disabled: true }
11+
} else {
12+
var bridge = ReactNative.NativeModules['{{{nativeModule}}}']
13+
14+
if (!bridge) {
15+
throw new Error('Failed to load {{{name}}} integration native module')
16+
}
17+
18+
module.exports = bridge.setup
19+
}

0 commit comments

Comments
 (0)