App crashes on start when remote debugging is disabled - react-native

I am trying to install my react-native app on my phone (iPhone). It installs alright but then crashes on start with this error message -
undefined is not an object (evaluating 'navigator.userAgent.indexOf')
<unknown>
:12:71
loadModuleImplementation
require.js:213:12
<unknown>
getScrollPosition.js:12:31
If i then enable remote js debugging, it reloads and everything works fine. I disable remote debugging, the app goes back to crashing. Any idea what might be happening here?
Update - The culprit code is in fbjs package - https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/dom/getDocumentScrollElement.js
They check if navigator is defined or not and then try to access the second level property on it - navigator.userAgent.indexOf.
I can either fake navigator.userAgent somehow or send a PR to fbjs.

navigator is a global Web API available in browsers. This is not available in React Native as it's not a web browser. All of the Web APIs are not part of the global environment. This is why navigator.userAgent.indexOf is throwing the undefined error.
Now the reason why your program runs fine when debugging JS remotely is because React Native will switch to using the JavaScript engine provided by Chrome (or whatever you are debugging through) instead of the core one when you remote debug. So when debugging, you will have access to the global Web API that browsers normally have.
This is a very tricky gotcha that will often trip people up as most people develop with debugging turned on all the time. Rule of thumb: React Native is not a browser. Don't use any of the globals that you would normally use when doing web development and you'll avoid most of these types of gotcha errors.
If you would like to see how these globals are polyfilled (often with empty objects) in React Native's JavaScript engine, you'll want to look at initializeCore.js. Here you can see that React Native will polyfill navigator like this:
// 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'));
Edit: To answer the follow-up and give a workaround.
You can shim it, but you need to do it before importing any of your other files in index.js (the root of your application). This is how it's done in node-libs-react-native with their globals.js file where they too set a default user agent string. Adapting that, you can achieve the same result by doing the following:
Create file to hold your shims, globals.js:
global.navigator.userAgent = 'React Native';
Import/Require it prior to importing any of your other files in index.js:
import { AppRegistry } from "react-native";
import globals from "./globals";
import App from "./App";
AppRegistry.registerComponent("RNSandbox", () => App);
If for some reason you want the userAgent to be different or be dependent on whether you are debugging or not, you can add your own logic to the globals.js.

Related

Use a third-party script tag in React Native

I am trying to add an external script to my React Native app. The script is not available as an NPM package, so a tag is required.
The script requires me to attach a function to the window object. That function is triggered when the script loads. window.onExampleScriptReady = () => {}
I added polyfills for the window/document.
This code works perfectly in a web browser, but yields nothing on iOS. Not even any errors.
const script = document.createElement("script")
script.src = "https://my-example-script.js"
script.async = true
document.body.appendChild(script)
My solution does not require dynamic/runtime tag creation, so I'm open to solutions similar to adding a script tag in the index.html file. (which I don't believe React Native has)

How to setup feathers offline in react native

I would like to know if anyone successfully set up feathers offline in react native. Right now I am having an issue whenever I call "owndataWrapper" i.e
import { owndataWrapper } from '#feathersjs-offline/client';
owndataWrapper(app, '/messages', {});
The error says Unable to resolve module path in /node-localstorage/LocalStorage.js . . so I ended up installing these packages.
assert, constants, events, path, stream, and fs
and got a new error.
here is the error.
https://github.com/feathersjs-offline/owndata-ownnet/issues/46
My guess is probably due to the fs package, it has a security issue.
Any idea? Thanks
After digging further it turns out it only works on web apps. It uses packages that does not exists in react native such as path, process, fs, and so on. I tried using
https://github.com/parshap/node-libs-react-native
and
https://github.com/staltz/react-native-process-shim
but got stuck and continuesly having error on fs. . in conclusion I need to drop the ball for now since this feathers offline is not yet fully created for react native.

Unit test case is failing in my React app because of some issue in fabric

I am new to react and also wanted to use office react ui for one of our requirement i followed the git hub and able to use office ui react components in my components but while running my first test case for App.js it is giving me below error.
E:\net_react\my-new-app\ClientApp\node_modules\office-ui-fabric-react\lib\Fabric.js:1
({"Object.":function(module,exports,require,__dirname,__filename,global,jest){export * from './components/Fabric/index';
^^^^^^
SyntaxError: Unexpected token export
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/ScriptTransformer.js:289:17)
at Object. (src/components/Login.js:13:592)
at Object. (src/components/Home.js:2:14)
And i have an import statement in my Login.js
import { Fabric } from '../../node_modules/office-ui-fabric-react/lib/Fabric';
The error is because your test harness does not support ES 6 modules (which is what is in lib in Fabric 6).
Try importing instead from office-ui-fabric-react/lib-commonjs/Fabric or office-ui-fabric-react (which has bundle size implications unless you're able to utilize Tree Shaking) or modify your test harness's module map to redirect lib/ imports into lib-commonjs.
Update
To elaborate on the answer above, the Fabric release notes has guidance for Jest configuration:
moduleNameMapper: {
"office-ui-fabric-react/lib/(.*)$": "office-ui-fabric-react/lib-commonjs/$1"
}

Unable to resolve module (Expo, React Native)

Building a React Native app with Expo, the Javascript bundle fails after getting the error Unable to resolve "../stores/__fixtures__/matchlist/matchlistSourceFixture" from "src/containers/MatchlistSwipeContainer.tsx", despite the fact that I am 100% sure this file exists and its relative path in this instance is correct – especially as I’m using VSCode and it complains if the path isn’t right and I’m using VSCode’s autocomplete to begin with.
If I move the file into any other directory that is not with __ dunder affixes and update the relative path accordingly, it can find the file perfectly fine.
I’ve checked other similar topics with Unable to resolve module errors, but they all seem to be related to third-party packages, whereas this is a local file.
Import statement:
import { matchlistSourceFixture } from '../stores/__fixtures__/matchlist/matchlistSourceFixture';
Export statement in the file in matchlistSourceFixture.ts:
export const matchlistSourceFixture = {...}
Attached is an image of the error message in the Expo iOS app. The message stating that the file doesn’t even exist (it has a .ts extension by the way) makes me think the relative path isn’t really the issue here anyway.
Versions:
React 16.3.1
Expo 27.0.0
Exp 54.0.0
It seems like __fixtures__ dirs are blacklisted by default in RN: react-native/local-cli/util/Config.js.
See this comment on overriding the default.

After bundling my aurelia app I get a: No PLATFORM.Loader error

After bundling a simple aurelia application with jspm bundle-sfx I get the following error:
No PLATFORM.Loader is defined and there is neither a System API (ES6) or a Require API (AMD) globally available to load your app.
An example application: https://github.com/Baudin999/jspm-bundling-test
You can use: npm run setup:dev in a non windows env to switch back to the dev settings (which is just a comment/uncomment in the ./src/client/index.html) and you can use npm run setup:prod to switch back to the production environment, bundling will automatically be triggered. all other scripts can be found in the package.json.
I can't link to other questions because I haven't found any questions which relate to this problem. I "think" (which means absolutely nothing) that this might be related to the fact that aurelia needs a full loader even when bundling with bundle-sfx but I haven't found any ways to solve the error.
EDIT (25/01/2017 17:16): I've found out that the error is because I import the aurelia-bootstrapper.
As soon as I add: import * as bootstrapper from 'aurelia-bootstrapper'; I get the error
Please add the code how do you bootstrap your aurelia app.
There is nothing actually to import from bootstrapper apart from bootstrap function.
Which you would use in case of custom manual bootstrapping.
like in
import { bootstrap } from 'aurelia-bootstrapper'
const configure: (au: Aurelia) => {} = async function (au: Aurelia) {
au.use
.standardConfiguration();
await au.start()
au.setRoot() // or au.enchance()
})
bootstrap(configure)
in a happy path scenario with jspm - you System.import('aurelia-bootstrapper')
and it takes over finding the root node of your app and the script to configure Aurelia (main by default)
Have a look at Bootstrapping Aurelia in the docs
Oh.. and bundle-sfx is not supported there are other means to bundle aurelia apps using jspm