I have a project where both a mobile app and a web app are integrated into the same server and repository. The React components are loaded dynamically based on the environment like this:
import React from "react";
class Sheet extends React.Component {
constructor(props) {
super(props);
this.state = {
componentLoaded: false,
Component: null,
};
}
componentDidMount() {
if (!!process.env.EXPO_PUBLIC_PROJECT_ROOT) {
this.setState({ Component: require('./mobile').default, componentLoaded: true });
} else {
this.setState({ Component: require('./web').default, componentLoaded: true });
}
};
render = () => {
if (!this.state.componentLoaded) {
return null; // or a loading indicator, e.g. <div>Loading...</div>
}
return React.createElement(this.state.Component, this.props);
};
}
export default Sheet;
This setup works fine on mobile, but when I run the web application, I encounter the following error related to the expo-barcode-generator library:
: Module parse failed: Unexpected token (44:4)
|
| return (
<Svg
| x={0}
| y={0}
Here are the files that reference the expo-barcode-generator and react-native-view-shot libraries:
import * as Print from 'expo-print';
import * as FileSystem from 'expo-file-system';
import { captureRef } from 'react-native-view-shot';
import ProductionOrderSheet from "../../ProductionOrderSheet"
const printSheet = async (viewRef) => {
try {
const uri = await captureRef(viewRef, {
format: "png",
quality: 1.0
})...
};
const Sheet = (props) => {
const { appContext, type, sheet } = props;
switch (type) {
case "productionOrderSheet":
return (
<ProductionOrderSheet
{...sheet}
type={"productionOrderSheet"}
printSheet={printSheet}
appContext={appContext}
/>
);
default:
throw new Error(`(Sheet) the sheet type ${type} not found`);
}
}
export default Sheet
import Table from "../../Table";
import Button from '../../Button';
import Container from "../../Container"
import TextFormatter from "../../TextFormatter"
import { Barcode } from 'expo-barcode-generator';
const MobileProductionOrderSheet = (props) => {
...
const getHeader = () => {
return (
<Barcode
value={productionLot}
options={{ format: 'CODE128', background: 'white', height: 70, fontSize: 18 }}
/>
</Container>
</Container>
)
}
...
package.json:
{
"name": "@monorepo/appmobile",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "expo start",
"android": "expo run:android",
"ios": "expo run:ios",
"web": "expo start --web"
},
"dependencies": {
"@apollo/client": "^3.10.8",
"@expo/ngrok": "^4.1.3",
"@fortawesome/fontawesome-svg-core": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-native-fontawesome": "^0.3.2",
"@react-native-community/datetimepicker": "8.0.1",
"@react-native-picker/picker": "2.7.5",
"@react-navigation/drawer": "^6.6.15",
"@react-navigation/material-top-tabs": "^6.6.13",
"@react-navigation/native": "^6.1.17",
"@react-navigation/native-stack": "^6.10.0",
"core-js": "^3.37.1",
"expo": "~51.0.21",
"expo-barcode-generator": "^3.0.2",
"expo-navigation-bar": "^3.0.6",
"expo-print": "^13.0.1",
"expo-screen-orientation": "~7.0.5",
"expo-secure-store": "~13.0.2",
"expo-status-bar": "~1.12.1",
"graphql": "^16.9.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.74.3",
"react-native-gesture-handler": "~2.16.1",
"react-native-media-query": "^2.0.1",
"react-native-pager-view": "6.3.0",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "3.31.1",
"react-native-svg": "15.2.0",
"react-native-tab-view": "^3.5.2",
"react-native-vector-icons": "^10.1.0",
"react-native-view-shot": "^3.8.0",
"react-native-web": "~0.19.10",
"socket.io-client": "^4.7.5"
},
"devDependencies": {
"@babel/core": "7.19.6",
"@types/react-native": "^0.73.0"
},
"private": true
}
Commenting out the library imports: I commented out the imports for expo-barcode-generator and react-native-view-shot, and the code worked on the web but not on mobile, as the component could not be used.
// import { Barcode } from ‘expo-barcode-generator’;
// import { captureRef } from ‘react-native-view-shot’;
Commenting out the conditional mobile import: I also tried commenting out the conditional import for mobile, which made the web work, but then I couldn’t use the component on mobile.
if (!!process.env.EXPO_PUBLIC_PROJECT_ROOT) {
// this.setState({ Component: require('./mobile').default, componentLoaded: true });
} else {
this.setState({ Component: require('./web').default, componentLoaded: true });
}
Finally, I attempted to use dynamic require for the libraries, like this:
if (!!process.env.EXPO_PUBLIC_PROJECT_ROOT) {
const Barcode = require('expo-barcode-generator');
}
but it not works