React Native 中的条件导入

IT技术 javascript reactjs react-native webpack
2021-03-26 06:13:45

我在 React Native 中使用条件导入时遇到了一些麻烦。

我有一些在 React Web 应用程序和 React Native 中使用的文件。

我想要什么:

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

因为 'some_file' 导入react_router.

然而,这个导入仍在发生,RN 地铁打包器抛出

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

即使我将其替换为:

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

它仍然尝试加载some_file. 无论如何,如果满足条件,是否只导入/需要此文件?

干杯!

编辑:我尝试过的事情:

5个回答

平台特定的进口

您可以将导入放置在带有native.js扩展的组件中,它只会绑定到移动设备 (ios/android)。例如 MyComponent.native.js 然后你有一个同名但.js扩展名相同的 web 组件例如我的 Component.js

当您从 './components/MyComponent' 导入 MyComponent 时,正确的一个将被导入而另一个被忽略。

经过一番搜索,结果发现动态导入可能有点痛苦。

这是我想出的解决方案,我已经在 node.js 中尝试过了。

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

或者,我想你可以做这样的事情;

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

但问题是这些都需要以任何方式导入module。

let module; if(true) { module = require(MODULE); }? 我们对项目中的开发工具module做了类似的处理。
2021-05-28 06:13:45

特定于平台的导入很好,但在网络上无济于事。

react-native部分package.json是你的朋友:

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

有了这个设置

// 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

文档可以在这里找到它是针对该browser部分的,但该react-native部分的工作方式相同。

我遇到了一个问题,我正在使用的项目正在使用react-native-tvos,我尝试添加react-native-ad-manager为依赖项,但它不支持 tvOS,因此我想为非 tvOS 平台动态导入广告管理器依赖项。我能够让它像这样工作:

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 />
  )
}

对于 React-navive-web,我们可以使用特定于平台的管理代码,这些代码将在移动应用程序和 Web 中进行管理。

特定于 Web 的代码 # 较小的平台差异可以使用 Platform module。

import { Platform } from 'react-native';

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

例如,在您的项目中使用以下文件:

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

从 './MyComponent' 导入 MyComponent;React Native 将自动为每个特定的目标平台导入正确的变体。