Expo web build fails because of JSX in .js files - react-native

I have a Expo project to which I added victory-native library. When building for the web, Webpack complains about missing loader. The errors are of this pattern below and appear for all the files from this particular library
./node_modules/victory-native/src/components/victory-clip-container.js 10:22
Module parse failed: Unexpected token (10:22)
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
|
| export default class extends VictoryClipContainer {
> static defaultProps = Object.assign({}, VictoryClipContainer.defaultProps, {
| groupComponent: <G />,
| rectComponent: <Rect />,
How do I add the correct loader? Do I add something to the babel config? Or should I override the webpack configuration?
Babel is currently using only babel-preset-expo

As stated by Michael, native and web code can be differentiated using the naming in the files.
A simple complete solution is:
victory.js:
import * as Victory from 'victory';
export default Victory;
victory.native.js:
import * as Victory from 'victory-native';
export default Victory;
And when you want to use the victory:
import Victory from "./victory"; // this will default to victory.js or victory.native.js
// depending on the compilation target platform.
const VictoryBar = Victory.VictoryBar;
const VictoryChart = Victory.VictoryChart;
const VictoryTheme = Victory.VictoryTheme;
...
{
...
return <View style={styles.container}>
<VictoryChart width={350} theme={VictoryTheme.material}>
<VictoryBar data={data} x="quarter" y="earnings" />
</VictoryChart>
</View>
}

Whilst using victory-native in Expo apps that target iOS & Android is fully supported, we do not support building for the web with victory-native.
However, as both victory-native and victory share the same public API, it's possible to configure your Expo project to automatically use victory-native when building your native apps for iOS & Android, and victory when building your web app.
yarn add -D #expo/webpack-config
Then, create a webpack.config.js file at the root of your Expo project
const createExpoWebpackConfigAsync = require('#expo/webpack-config');
module.exports = async function(env, argv) {
const config = await createExpoWebpackConfigAsync(env, argv);
// resolve victory-native as victory for the Web app
config.resolve.alias['victory-native'] = 'victory';
return config;
};
Refered from the official documentation .

You cannot use victory-native imports for web and you cannot use victory import for react native.
I solved the issue by creating an file named victory.native.ts and victory.ts which containing all necessary imports.
victory.native.ts:
import * as Victory from 'victory-native'
victory.ts:
import * as Victory from 'victory'
Now you can import victory.ts in web and app.

Related

React-native-web Multi-Platform Setup using Expo 44 + Typescript

What is the simplest way to implement Multi-Platform Setup for a component in Expo. I have tried mamy diferent ways.. it was working on web but it is failing on Native and failing with Jest & #testing-library/react-native. Ideally I would like the least amount of custom config etc (do not want to eject). I expect the file structure to look like this:
Component
|- index.tsx
|- Component.native.tsx
|- Component.web.tsx
I am not sure how to do the index.tsx. I saw someone say something like this would work:
// index.tsx
// #ts-ignore
export { default } from "Component"
this didn't work so I did
// index.tsx
// #ts-ignore
export { default } from "./Component"
This worked for web, but the jest test said
Cannot find './Component'
However, Jest was able to find:
'./Component.mobile.tsx'
'./Component.web.tsx'
I tried:
// index.tsx
// #ts-ignore
import Component from "./Component";
export default Component
and the tests was the same
and the native emulator said:
Unable to resolve module ./Component
I tried using lazy loading but this does not work on web.
import { lazy, Suspense } from "react";
import { Platform } from "react-native";
import Loading from "../../components/Loading";
import { ComponentType } from "./types";
const Web = lazy(() => import("./Component.web"));
const Mobile = lazy(() => import("./Component.mobile"));
const Component: ComponentType = (props) => {
const isWeb = Platform.OS === "web";
return (
<Suspense fallback={<Loading message="Loading Component" />}>
{isWeb ? <Web {...props} /> : <Mobile {...props} />}
</Suspense>
);
};
export default Component
Questions
how to use diferent files for components depending on platform (exlude other files from build)
how to make it ok with ts in vscode
Using Expo 44. Thanks
I would use named exports. So begin by having the same component name in both files. Next I would have one file called Component.tsx and the other Component.native.tsx. That will be enough to allow the bundler to pull the native for native and the other for non-native (in other words web). That should be all you need.

How to switch app’s UI and the Storybook UI

I am setting up Storybook to develop components in my app, what is the best way to switch between UI's?
Currently I am replacing my app entry with :
export default from './storybook';
How do I remove this when in production?
yarn add react-native-config, then pod install
If you're developing for Android, add an import line as described here
In your project root, create an .env file
Any environment variables you add to .env
can be accessed as Config.YOUR_ENVIRONMENT_VARIABLE
Now, add the environment variable LOAD_STORYBOOK=true to .env.
In App.tsx, change your code like below so that Storybook is rendered conditionally.
import StorybookUI from './storybook'
import Config from 'react-native-config'
const App = () => {
return (
// Your actual app
)
}
export default Config.LOAD_STORYBOOK === 'true' ? StorybookUI : App

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 configure App.js in react-native to use React-native-ui-kitten?

I am a newbie in react-native and I'm trying to use the react-native-ui-kitten library. The problem is that the documentation is not really helpful.
I have I have installed ui-kitten and the theme as indicated with the command: npm i react-native-ui-kitten #eva-design/eva
The documentation asks to configure the application root which I consider to be the App.js file unless I'm wrong.
So i changed the App.js generated code to this:
import React from 'react';
import {
mapping,
theme,
} from '#eva-design/eva';
import { ApplicationProvider } from 'react-native-ui-kitten';
import { Application } from './path-to/root.component';
export default class App extends React.Component {
public render(): React.ReactNode {
return (
<ApplicationProvider
mapping={mapping}
theme={theme}>
<Application/>
</ApplicationProvider>
);
}
}
Unfortunetely it's not working.
Has anyone recently used ui-kitten library ?
What does the documentation mean by Application Root and how to set up a simple react-native project to use react-native-ui-kitten?
And yes I actually checked the documentation but maybe there is something I am not doing right.
I ran into the same problem.
I discovered that the creators of this UI kit use in fact in their code examples Typescript.
So you need to recreate your Reactnative project using a Typescript template, then rename accordingly the App.js into App.tsx
Any other components need to be renamed with the extension .tsx.
Make sure you read about Typescript:
https://www.typescriptlang.org
Here it is how you can recreate your project with Typescript:
https://facebook.github.io/react-native/blog/2018/05/07/using-typescript-with-react-native
All the best,
I am also a beginner in react-native and it seems we kinda differ in implementing the code. I am not sure if this would help but this is the way I implement your code:
import * as React from 'react';
import { mapping, light as lightTheme } from '#eva-design/eva';
import { ApplicationProvider } from 'react-native-ui-kitten';
import { Application } from './path-to/root.component';
const App = () => (
<ApplicationProvider
mapping={mapping}
theme={lightTheme}>
<Application/>
</ApplicationProvider>
);
export default App;
You could try it and let me know if this suits you. Good luck!

How to show all dependencies, third party of react native app on Settings app

I want to show all dependencies, third party of react native app on Settings app same as https://github.com/mono0926/LicensePlist.
Are React Native support it ?
You can easily list all of your project dependencies. The tricky (and not sure how feasible) part would be to get the dependencies of your dependencies (and so forth).
If you want to get your own dependencies, you can use this code:
import packageJson from '../package.json'
const getAllDependencyNames = ({ dependencies, devDependencies }) => [
...Object.keys(dependencies),
...Object.keys(devDependencies),
];
// If getAllDependencies is a class function, use this.getAllDependencies
const myDependencies = getAllDependencyNames(packageJson);
This will merge all dependencies and devDependencies into a single Array. You can then iterate over them to render them.
render() {
<FlatList
data={myDependencies}
renderItem={({dependency}) => <Text>{dependency}</Text>}
/>
}