Platform specific imports

Trying to get expo web to work and running into issues with some of the libraries I use for native, e.g. Branch, react-native-maps, and Segment.

I’m not sure what the solution is to this problem but one might be being able to conditionally import libraries. I don’t think I’ve seen a straight-up if (Platform.OS !== 'web') import Branch from 'expo-branch'; before but I do think this has been done with platform specific file extensions, so you can make “component.ios.js”, “component.android.js”, and “component.web.js” and expo runs/compiles only the one corresponding to the current platform. (if this makes sense, I put it as a feature request here). Another way to conditionally import libraries could be with code-splitting / lazy loading modules. That would be great too, but I’m more just looking for a way I could conditionally import.

Here’s screenshots of the errors I’ve been getting. The first error is from Branch. The second error is from react-native-maps and shows up when I remove all import of Branch in my code. The third error is from Segment and shows up when I remove all imports of react-native-maps in my code. I haven’t tried removing Segment. Either way we’d like to keep all of these for our mobile clients.

image

image

I’m not sure why this works but import doesn’t work like this, but I’ve had luck with code like:

let thingINeedToImport;
if (something) {
   thingINeedToImport = require('thingineedtoimport');
}
1 Like

Wow, I can’t believe I didn’t try that. That’s exactly what I’m looking for!!! Trying it now and it’s working so far.

import { Platform } from "react-native";

let Branch, BranchEvent;

if (Platform.OS !== 'web') {
  Branch = require('react-native-branch').default;
  BranchEvent = require('react-native-branch').BranchEvent;
}

export default Branch;
export { BranchEvent };
import { Platform } from "react-native";

let MapView, Marker;

if (Platform.OS !== 'web') {
  MapView = require('react-native-maps').default;
  Marker = require('react-native-maps').Marker;
}

export default MapView;
export { Marker };
import { Platform } from "react-native";

let Segment;

if (Platform.OS !== 'web') {
  Segment = require('expo-analytics-segment');
}

export default Segment;
2 Likes

I just ran into this post. Maybe something worth looking into is that link: https://reactnative.dev/docs/platform-specific-code

Especially the part about naming the files differently to automatically import the ones you need

For example, say you have the following files in your project:

BigButton.ios.js
BigButton.android.js

You can then require the component as follows:

import BigButton from './BigButton';

React Native will automatically pick up the right file based on the running platform.

And for web-only files:

Container.js # picked up by Webpack, Rollup or any other Web bundler
Container.native.js # picked up by the React Native bundler for both Android and iOS (Metro)

It is a bit convoluted, but it helped me split some imports into 2 separate files and work around some error with @react-community packages not being compiled by webpack.

1 Like