禁用远程调试时,应用程序在启动时崩溃

时间:2018-04-12 14:01:24

标签: react-native react-native-ios

我正在尝试在手机(iPhone)上安装我的react-native应用程序。它安装正常但随后在此错误消息时崩溃 -

navigator

如果我然后启用远程js调试,它会重新加载,一切正常。我禁用远程调试,应用程序恢复崩溃。知道这里可能会发生什么吗?

更新 - 罪魁祸首代码在fbjs包中 - https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/dom/getDocumentScrollElement.js

他们检查是否定义了navigator.userAgent.indexOf,然后尝试访问其上的第二级属性 - navigator.userAgent

我可以以某种方式伪造{{1}}或向fbjs发送PR。

1 个答案:

答案 0 :(得分:7)

navigator是浏览器中提供的全局Web API。这在React Native中不可用,因为它不是Web浏览器。所有Web API都不是全局环境的一部分。这就是navigator.userAgent.indexOf抛出undefined错误的原因。

现在,在远程调试JS时,程序运行正常的原因是,当您进行远程调试时,React Native将切换到使用Chrome提供的JavaScript引擎(或者您正在调试的任何内容)而不是核心引擎。因此,在调试时,您将可以访问浏览器通常具有的全局Web API。

这是一个非常棘手的问题,因为大多数人一直在调试开启的情况下经常绊倒人们。经验法则:React Native不是浏览器。不要使用在进行Web开发时通常使用的任何全局变量,并且您将避免大多数这些类型的错误。

如果您想在React Native的JavaScript引擎中看到这些全局变量是如何被填充的(通常是空对象),您需要查看initializeCore.js。在这里,您可以看到React Native将像这样填充navigator

// Set up Geolocation
let navigator = global.navigator;
if (navigator === undefined) {
  global.navigator = navigator = {};
}

// see https://github.com/facebook/react-native/issues/10881
polyfillObjectProperty(navigator, 'product', () => 'ReactNative');
polyfillObjectProperty(navigator, 'geolocation', () => require('Geolocation'));

修改:要回答后续行动并提供解决方法。

您可以对其进行填充,但在导入index.js(应用程序的根目录)中的任何其他文件之前,您需要执行此操作。这是how it's done in node-libs-react-native及其globals.js文件,他们也设置了默认的用户代理字符串。通过执行以下操作,您可以实现相同的结果:

  1. 创建文件以保留垫片globals.js

    global.navigator.userAgent = 'React Native';
    
  2. 导入/在导入index.js中的任何其他文件之前需要它:

    import { AppRegistry } from "react-native";
    import globals from "./globals";
    import App from "./App";
    
    AppRegistry.registerComponent("RNSandbox", () => App);
    
  3. 如果由于某种原因您希望userAgent不同或依赖于您是否正在调试,您可以将自己的逻辑添加到globals.js