Reputation: 748
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:
Upvotes: 25
Views: 20124
Reputation: 1494
I came across a problem where the project I am working on is using react-native-tvos
and I tried to add react-native-ad-manager
as a dependency but it doesn't support tvOS so I wanted to dynamically import the ad manager dependency for non tvOS platforms. I was able to get it to work like such:
import {Platform} from 'react-native';
const NullComponent = (props: any) => null;
const AdComponent = () => {
const [Banner, setBanner] = React.useState(() => NullComponent);
if (!Platform.isTV) {
import('react-native-ad-manager')
.then(({Banner: AdBanner}) => {
setBanner(() => AdBanner);
})
}
return (
<Banner />
)
}
Upvotes: 3
Reputation: 13843
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.
Upvotes: 4
Reputation: 2379
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.
Upvotes: 3
Reputation:
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.
Upvotes: 9
Reputation: 1456
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.
Upvotes: 13