【问题标题】:Conditional imports in React NativeReact Native 中的条件导入
【发布时间】:2018-10-24 17:41:21
【问题描述】:

我在让条件导入在 react native 中工作时遇到了一些麻烦。

我有一些文件用于 React Web 应用程序和 React Native。

我想要什么:

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

因为 'some_file' 导入 react_router

但是,此导入仍在进行中,并且 RN Metro 捆绑器抛出

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

即使我将其替换为:

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

它仍然尝试加载some_file。是否只有在满足条件时才导入/需要此文件?

干杯!

编辑: 我尝试过的事情:

【问题讨论】:

    标签: javascript reactjs react-native webpack


    【解决方案1】:

    我遇到了一个问题,我正在处理的项目使用 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 />
      )
    }
    

    【讨论】:

      【解决方案2】:

      Platform specific imports 很好,但不会在网络上为您提供帮助。

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

      "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
      

      可以在here 找到文档。它适用于 browser 部分,但 react-native 部分的工作方式相同。

      【讨论】:

        【解决方案3】:

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

        Web-specific code # 微小的平台差异可以使用Platform 模块。

        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 会自动为每个特定的目标平台导入正确的变体。

        【讨论】:

          【解决方案4】:

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

          这是我想出的解决方案,我在node上试过了。

          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());
          

          但问题是这些需要一个模块以任一方式导入。

          【讨论】:

          • let module; if(true) { module = require(MODULE); } ?我们在项目中对开发工具模块进行了类似操作。
          • 注意:如果你想要默认导出,你应该访问从require函数返回的'default'键:const MODULE_NAME = &lt;CONDITION&gt; ? require(MODULE_A).default : require(MODULE_B).default;
          【解决方案5】:

          Platform specific imports;

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-06-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-11-23
            • 1970-01-01
            • 2020-11-04
            • 1970-01-01
            相关资源
            最近更新 更多