Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional imports in React Native

I'm having a bit of trouble getting conditional imports working in react native.

I have some files that are used in a react web app and in react native.

What I'd like:

if(process.env.REACT_PLATFORM === 'WEB') {
    import('some_file').then(({someFunc})=> someFunc())
}

Because 'some_file' imports react_router.

However, this import is still happening, and the RN metro bundler throws

UnableToResolveError: Unable to resolve module 'react-router' from 'some_file'.

Even If I replace it as:

if(false) {
    import('some_file').then(({someFunc})=> someFunc())
}

It still trys to load some_file. Is there anyway to only import/require this file if a condition is met?

Cheers!

EDIT: Things I've tried:

  • Require instead of import.
  • https://babeljs.io/docs/plugins/syntax-dynamic-import/
like image 864
James Adams Avatar asked May 15 '18 00:05

James Adams


4 Answers

Platform specific imports are nice but won't help you on the web.

react-native section in package.json is your friend:

"react-native": {
  "module1": false,
  "module2": "module3"
}

with this setup

// module1
export const x = 1

// module2
export const x = 2

// module3
export const x = 3

// will result in
import {x} from 'module1'
console.log( x === undefined ) // in the react-native environment
console.log( x === 1 ) // in the browser

import {x} from 'module2'
console.log( x === 3 ) // in the react-native environment
console.log( x === 2 ) // in the browser

import {x} from 'module3'
console.log( x === 3 ) // in the react-native environment
console.log( x === 3 ) // in the browser

The docs can be found here. It's for the browser section, but the react-native section works the same way.

like image 72
x00 Avatar answered Oct 27 '22 16:10

x00


For React-navive-web we can use manage code for platform-specific that will manage in Mobile App and Web Also

Web-specific code # Minor platform differences can use the Platform module.

import { Platform } from 'react-native';

const styles = StyleSheet.create({
  height: (Platform.OS === 'web') ? 200 : 100,
});

For example, with the following files in your project:

MyComponent.android.js
MyComponent.ios.js
MyComponent.web.js
And the following import:

import MyComponent from './MyComponent'; React Native will automatically import the correct variant for each specific target platform.

like image 44
user1374 Avatar answered Oct 27 '22 18:10

user1374


Platform specific imports;

You can place the import in a component with the native.js extension and it will only be bundled for mobile (ios/android). e.g. MyComponent.native.js Then you have a component for web with the same name but the .js extension. e.g. My Component.js

When you import MyComponent from './components/MyComponent', the correct one will be imported and the other ignored.

like image 8
Shagymoe Avatar answered Oct 27 '22 16:10

Shagymoe


After a bit of searching, in turns out dynamic imports can be a bit of a pain.

This is the solution I came up with, I've tried it in node.

const MODULE_NAME = <CONDITION> ? require(MODULE_A) : require(MODULE_B);

Alternatively, I guess you could do something like this;

const MODULE_TO_IMPORT = 'MODULE_IMPORT_STRING';
const MODULE_NAME = import(MODULE_TO_IMPORT).then(({someFunc}) => someFunc());

But the problem is that these require a module to be imported either way.

like image 7
harryparkdotio Avatar answered Oct 27 '22 17:10

harryparkdotio