Expo React Native: Code Splitting Incompatible Web Packages - react-native

I have a component that uses #stripe/stripe-react-native named NativeCheckout.
This package does not work on web (Chrome), and when I import it I get an error:
Failed to compile
/home/joey/Projects/project/project_frontend/node_modules/#stripe/stripe-react-native/lib/module/components/StripeProvider.js
Module not found: Can't resolve '../../package.json' in '/home/joey/Projects/project/project_frontend/node_modules/#stripe/stripe-react-native/lib/module/components'
So if I run it in my browser, I do not want this component. This component is only rendered on native apps. I have found three alternative ways to import the Component. If my code is working fine then I add any of the follow lines, the above error is happening. I thought this would not load in the problem code.
const loadNative = async () => {
await import("./NativeCheckout")
}
const NativeCheckout = lazy(() => import("./NativeCheckout"));
const NativeCheckout = lazy(() => import("./NativeCheckout"));
Does anyone know a way to make this work?
TIA

Related

Error using React Native using bitcoinjs-lib and ECpair / tiny-secp256k1

I'm trying to use bitcoinjs-lib, but I get errors, I think it has to do with the explanation to use browserify.
For this:
import BIP32Factory from 'bip32';
const tinysecp = require('tiny-secp256k1')
const bip32 = BIP32Factory(tinysecp);
I get the following:
Uncaught TypeError: ecc.isPoint is not a function
at Object.testEcc (testecc.js:5:1)
at BIP32Factory (bip32.js:9:1)
Here's an alternative, and I get a different error:
import { Signer, SignerAsync, ECPairInterface, ECPairFactory, ECPairAPI, TinySecp256k1Interface } from 'ecpair';
const tinysecp: TinySecp256k1Interface = require('tiny-secp256k1');
const bip32: ECPairAPI = ECPairFactory(tinysecp);
Results in following error:
./node_modules/ecpair/src/ecpair.js 66:7
Module parse failed: Unexpected token (66:7)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| }
| class ECPair {
> __D;
| __Q;
| compressed;
Separately I tried to browserify bitcoinjs-lib and ecpair, but I think I'm doing something wrong.
I think bitcoin-js and tinysec are not going to work as is, because they are using some Node Js Core Features that are not Available at Runtime in an react-native app.
You can take a look at:
https://github.com/novalabio/react-native-bitcoinjs-lib as a substitute
or
https://gist.github.com/coreyphillips/4d45160fed016417a5f583f179c2cbdb a discussion about how to add bitcoin-js to react-native using a shim file

Had so issue with jest react-native and bugsnag

I tried run Jest unit tests on React-Native with Bugsnag, but I got error:
The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
Consider using the "jsdom" test environment.
ReferenceError: window is not defined
1 | import React from 'react';
> 2 | import Bugsnag from '#bugsnag/react-native';
Solution which is working for me:
we need to add mock bugsnag interceptor to jestSetupFile.js
jest.mock('#bugsnag/react-native', () => ({
use(plugin) {
const boundary = plugin.init();
// we don't need the error boundary to swallow the errors, we want jest see them and fail the test
delete boundary.prototype.componentDidCatch;
return boundary;
}
}));
I fixed it with just mocking Bugsnag: jest.mock("#bugsnag/react-native", () => jest.fn());

mainBundlePath is Null for node package

I am using the package react-native-coreml and running into this error at startup.
My intention is to use this package to use a CoreML package in my react native app. I am running this within EXPO if that makes any difference.
I can't even run the app. These two errors are together.
Unable to start your application. Please refer to https://expo.fyi/no-registered-application for more information.
and
TypeError: null is not an object (evaluating 'RNCoreML.mainBundlePath')
- node_modules/react-native/Libraries/LogBox/LogBox.js:148:8 in registerError
Obviously the first error isn't useful, just including for thoroughness.
My implementation is as follows:
import React, { useState } from 'react'
import { StyleSheet, Text, View } from 'react-native'
import FaceScanner from './FaceScanner';
import { classifyImage } from "react-native-coreml";
const Onboarding = () => {
const [imageURL, setImageURL] = useState('');
const [tested, setTested] = useState(false);
console.log(imageURL)
if (imageURL !== '' && !tested) {
async () => {
// const { label, confidence } = await classifyImage(imageURL, './model.mlmodelc')
setTested(true);
console.log("The image is a " + label + ". I think. ")
}
}
...
edit I have ejected from expo as per a comment's suggestion. I am now encountering these errors.
BUNDLE ./index.js
ERROR TypeError: null is not an object (evaluating 'RNCoreML.mainBundlePath')
LOG Running "main" with {"rootTag":1,"initialProps":{}}
ERROR Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.
react-native-coreml is a library with native extensions that do not work in the expo managed workflow currently. you can read about the managed workflow limitations in the expo docs.
if you'd like to use it, run expo eject and build the project in xcode

You attempted to use a firebase module that's not installed on your Android project by calling firebase.app() - Jest testing

I'm trying to test my app using jest but encountered an error "You attempted to use a firebase module that's not installed on your Android project by calling firebase.app()". Below is my code
import firebase from '#react-native-firebase/app';
test('renders correctly', () => {
Platform.OS = 'android';
firebase.initializeApp({//credentials hidden
});
const _firestore = firebase.firestore();
const personStore = new PersonStore(_firestore);
const app = renderer
.create(
<Provider {...personStore}>
<PersonInfo />
</Provider>,
)
.getInstance();
});
What am I missing?
I've tried this solution https://rnfirebase.io/install-android but to no avail
And #react-native-firebase/app is working if I'm not in test mode
Try the getting started steps: Getting Started
The solution you tried is a secondary step.
Also firebase is segmented in modules, so you should install the required modules separated. if you are going to use the firestore you have to install the module.
Firestore Module
for me the problem was with mismatch in the package name of the app throughout the project (I started out with a MyApp project and then changed the name but not in all the necessary places).
I then followed these steps to rename everything and it started working

How to use enzyme for react-native with jest

I have followed –or tried to– several posts on how to do it, including the airbnb enzyme's guide for (separatedly) react-native and jest. (E.g: https://medium.com/#childsmaidment/testing-react-native-components-with-enzyme-d46bf735540#.6sxq10kgt, https://blog.callstack.io/unit-testing-react-native-with-the-new-jest-i-snapshots-come-into-play-68ba19b1b9fe#.4iqylmqh5 or How to use Jest with React Native)
But I keep getting lots of warnings (I have multiple set of concurrent tests) whenever I try to render (not mount, it crashes) any native component. Warnings are always about a native prop not being recognised.
Warning: Unknown props `focus`, `secureTextEntry` on <TextInput> tag. Remove these props from the element.
in TextInput (created by TextInput)
in TextInput (created by PasswordInput)
Anyone who has a set up working, recognises how to remove the warning or how to solve it?
Thanks
So I know this is a bit old but I was having issues with Jest, Enzyme, and React Native and I found this post - hopefully this solution will help.
To start with - Enzyme doesn't support mounting React Native and only supports shallow rendering. This wasn't good enough for me as I needed end-to-end tests from the component to the api which lead me to react-native-mock-render. What this does is allow us to run react native inside a browser environment which let's us test using Enzyme - all the calls for React Native and the components work as you would expect.
To set this up you'll need to install JSDOM, react-native-mock-render, Enzyme 3.0+, and Jest 20.0.0+. And then inside your jest setup file (which is specified in your package.json) include the following code:
const { JSDOM } = require('jsdom');
const jsdom = new JSDOM();
const { window } = jsdom;
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === 'undefined')
.map(prop => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
}
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: 'node.js',
};
copyProps(window, global);
// Setup adapter to work with enzyme 3.2.0
const Enzyme = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');
Enzyme.configure({ adapter: new Adapter() });
// Ignore React Web errors when using React Native
console.error = (message) => {
return message;
};
require('react-native-mock-render/mock');
And that's it - you're all setup to mount components in Enzyme and test them.
If you want to see a full sample check out react-native-mock-render-example. This is working with React 16, React Native 0.51, and Enzyme 3.2.
In order to unit test your component with jest you can use enzyme-to-json
npm install --save enzyme-to-json
then your test would look like this:
import { shallow } from 'enzyme';
import { shallowToJson } from 'enzyme-to-json';
import MyComponent from './MyComponent';
it('should render component', => {
expect(shallowToJson(shallow(<MyComponent />))).toMatchSnapshot();
});
I'm not sure regarding your case with react-native.
I can share my case of using jest + enzyme with standard react.
When I needed to test some component and isolate it from others I used jest.mock, e.g.
jest.mock('../ComponentToBeMocked', () => {
return () => null;
});
Initially I found examples when the second argument (a function) should return just a string representing a name of the mocked component. But in that case I saw that distracting Unknown props warning.