The Error
I’m early in learning to use React-Native, working with create-expo-app.
When I run npm start, I run into an error giving this output:
ERROR ReferenceError: Can’t find variable: Image
I expect that the second two errors are caused by the first error.
ERROR Invariant Violation: Failed to call into JavaScript module method AppRegistry.runApplication(). Module has not been registered as callable. Registered callable JavaScript modules (n = 11): Systrace, JSTimers, HeapCapture, SamplingProfiler, RCTLog, RCTDeviceEventEmitter, RCTNativeAppEventEmitter, GlobalPerformanceLogger, JSDevSupportModule, HMRClient, RCTEventEmitter. A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
ERROR Invariant Violation: Failed to call into JavaScript module method AppRegistry.runApplication(). Module has not been registered as callable. Registered callable JavaScript modules (n = 11): Systrace, JSTimers, HeapCapture, SamplingProfiler, RCTLog, RCTDeviceEventEmitter, RCTNativeAppEventEmitter, GlobalPerformanceLogger, JSDevSupportModule, HMRClient, RCTEventEmitter. A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
My Project I’ve built a minimal app that causes the error.
I ran:
npx create-expo-app TestImage
cd TestImage
npm install --save --legacy-peer-deps react-canvas-map
(react-canvas-map: https://www.npmjs.com/package/react-canvas-map)
App.js
The error originates from line 7: “new Image();”
import { StatusBar } from 'expo-status-bar'; import { StyleSheet, Text, View } from 'react-native'; import React, { useState } from 'react' import { Map, Marker } from 'react-canvas-map' const markerOneImage = new Image(); markerOneImage.src = './static/marker-blue.svg'; export default function App() { const [markerOneCoords, setMarkerOneCoords] = useState({ x: 100, y: 200 }) return ( <View style={styles.container}> <Text>Open up App.js to start working on your app!</Text> <StatusBar style="auto" /> <div style={{ height: '50vh', border: '1px solid #ddd', marginTop: '1rem' }}> <Map image={"./static/map.jpg"} > <Marker image={markerOneImage} markerKey={"marker-one"} coords={markerOneCoords} onDragTick={setMarkerOneCoords} onDragEnd={setMarkerOneCoords} onClick={() => { alert('You clicked marker one!') }} /> </Map> </div> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
The error occurs when I run
npm start
(which calls expo start
)
The entirety of my code either comes as the standard create-expo-app boilerplate code, or from a demonstrably working example: https://bor3ham.github.io/react-canvas-map/ (an example project on the react-canvas-map library).
Some Explanation
Image() is a HTML Standard element: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image
It is equivalent to “document.getElement(“img”). If I try that, I get the same error, for ‘document’.
ERROR ReferenceError: Can’t find variable: document
System Details
npm --version 8.19.3
package.json:
{ "name": "testimage", "version": "1.0.0", "main": "node_modules/expo/AppEntry.js", "scripts": { "start": "expo start", "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web" }, "dependencies": { "expo": "~47.0.6", "expo-status-bar": "~1.4.2", "react": "18.1.0", "react-canvas-map": "^0.1.8", "react-native": "0.70.5" }, "devDependencies": { "@babel/core": "^7.12.9" }, "private": true }
Have I set up my project incorrectly?
Am I missing an import that allows me to use HTMLImageElements from the HTML Standard Specification (https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement)?
Does React 18.1.0 (my version) require me to do something differently from the tutorial (running on 16.14.0) in relation to using “Image()”? I’ve tried setting react in package.json to 16.14.0, then re-running npm install and npm start (to match what I saw in the demo – https://bor3ham.github.io/react-canvas-map/ ). The same error occurs, though it notes:
Some dependencies are incompatible with the installed expo version: react@16.14.0 - expected version: 18.1.0 Your project may not work correctly until you install the correct versions of the packages. Install individual packages by running npx expo install react@18.1.0
I didn’t expect this problem to last as long as it has done. I haven’t found any sources talking about this as an issue, but I may have missed them as I don’t have a good grasp of what terms to use to search here.
Advertisement
Answer
I’ve worked this out now.
My question was effectively a duplicate of: Exception: Can’t find variable: document
Quoting an explanative answer from that question: https://stackoverflow.com/a/66003682/20535652
Unfortunately, both window and document are part of the web standard, not JavaScript (ECMA standard).
React Native uses JS to control rendering, but lack of DOM-manipuling itself, so you can not use many web-based APIs directly in React Native.
And that answer poses two possible options for resolution:
Using WebView in React Native app to load your web app
Try controling the React Native component yourself, rewrite logic