getting error after upgrading to expo sdk 44 to 46 - react-native

I have upgraded my expo application which was expo sdk 44 to expo sdk 46.
After upgrading I got this error and trying to figure this for last 4 days. Any help would be helpful..
Here is the error:
ERROR Invariant Violation: ViewPropTypes has been removed from React Native. Migrate to ViewPropTypes exported from 'deprecated-react-native-prop-types'.
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.
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:95:4 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:141:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/expo/build/errors/ExpoErrorManager.js:25:19 in errorHandler
at node_modules/expo/build/errors/ExpoErrorManager.js:30:24 in <anonymous>
at node_modules/#react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError
Steps I followed:
Upgraded Expo SDK into 45 and compiled successfully and then upgraded again into SDK 46
Tried registerRootComponent from a file named main.js refernece from expo
Also tried this answer which refers the multiple copies of react-native-safe-area-context tried this solution also

Fixed this issue:
Step 1:
Install the plugin
yarn add --dev babel-plugin-module-resolver deprecated-react-native-prop-types
Step 2:
create index.js file inside project folder resolver/react-native/ with following code
import * as StandardModule from 'react-native';
const deprecatedProps = {
ImagePropTypes: require('deprecated-react-native-prop-types/DeprecatedImagePropType'),
TextPropTypes: require('deprecated-react-native-prop-types/DeprecatedTextPropTypes'),
ViewPropTypes: require('deprecated-react-native-prop-types/DeprecatedViewPropTypes'),
ColorPropType: require('deprecated-react-native-prop-types/DeprecatedColorPropType'),
EdgeInsetsPropType: require('deprecated-react-native-prop-types/DeprecatedEdgeInsetsPropType'),
PointPropType: require('deprecated-react-native-prop-types/DeprecatedPointPropType'),
};
const imgProx = new Proxy(StandardModule.Image, {
get(obj, prop) {
if (prop === 'propTypes') return deprecatedProps.ImagePropTypes;
return Reflect.get(...arguments);
},
});
const txtProx = new Proxy(StandardModule.Text, {
get(obj, prop) {
if (prop === 'propTypes') return deprecatedProps.TextPropTypes;
return Reflect.get(...arguments);
},
});
// Had to use a proxy because ...StandardModule made think react-native that all modules were
// being used and was triggering some unnecessary validations / native dep checks.
// This prevents that from happening.
const objProx = new Proxy(StandardModule, {
get(obj, prop) {
if (prop in deprecatedProps) {
return deprecatedProps[prop];
}
if (prop === 'Image') {
return imgProx;
}
if (prop === 'Text') {
return txtProx;
}
return Reflect.get(...arguments);
},
});
module.exports = objProx;
Step 3:
configure module resolver inside babel.config.js, depends on your project requirement to blacklist/whitelist certain npm packages to prevent conflicting file.
example module-resolver config :
var path = require('path');
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
["module-resolver", {
"root": ["."],
resolvePath(sourcePath, currentFile, opts) {
if (
sourcePath === 'react-native' &&
!(
(
currentFile.includes('node_modules/react-native/') || // macos/linux paths
currentFile.includes('node_modules\\react-native\\')
) // windows path
) &&
!(
currentFile.includes('resolver/react-native/') ||
currentFile.includes('resolver\\react-native\\')
)
) {
return path.resolve(__dirname, 'resolver/react-native');
}
/**
* The `opts` argument is the options object that is passed through the Babel config.
* opts = {
* extensions: [".js"],
* resolvePath: ...,
* }
*/
return undefined;
}
}],
],
};
for reference this guide

Related

Unable to resolve module crypto

I am attempting to implement WalletConnect V1 in my React-Native Wallet app. However, whenever I use the following import:
import WalletConnect from "#walletconnect/client";
I get the following error:
Unable to resolve module crypto from /Users/<my-name>/<company-name>/<client-name>/<app-name>/node_modules/#walletconnect/randombytes/dist/cjs/node/index.js: crypto could not be found within the project or in these directories:
node_modules
I tried following some solutions but installing crypto-js and crypto-js#3.3.0 both did not fix the issue. I also already have react-native-crypto installed in my application.
Any help figuring out what I need to do to resolve this error would be amazing!
Just add custom resolver to your metro config
// metro.config.js
module.exports = {
resolver: {
extraNodeModules: {
crypto: require('react-native-cyrpto'),
},
},
};
Unfortunately crypto depends on other nodejs packages like: net, tls, fs and etc. Recommend using https://github.com/parshap/node-libs-react-native which polyfills node packages inside react-native
Docs
tldr;
nom install node-libs-react-native
// metro.config.js
module.exports = {
resolver: {
extraNodeModules: require('node-libs-react-native'),
},
};
I managed to solve this thanks to this post (https://github.com/parshap/node-libs-react-native/issues/23)
yarn add react-native-get-random-values
const nodelibs = require("node-libs-react-native");
nodelibs.crypto = `${__dirname}/src/crypto.js`;
module.exports = {
resolver: {
extraNodeModules: nodelibs,
},
};
Then created my own crypto.js file
// src/crypto.js
'use strict'
import { Buffer } from 'buffer';
const { NativeModules } = require('react-native');
const randomBytes = (size) => {
if (NativeModules.RNGetRandomValues) {
return Buffer(NativeModules.RNGetRandomValues.getRandomBase64(size));
} else {
throw new Error('Native module not found')
}
};
exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes;

Error: While trying to resolve module #apollo/client React Native

after installing new version of apollo client getting this Error. I tried other versions and to downgrade but nothing. Also I tried to specify in metro.config.js to resolve "cjs" type of file (#apollo/client/main.cjs), but nothing.
Error
error: Error: While trying to resolve module `#apollo/client` from file `****\src\api\queries\home.js`, the package `****\node_modules\#apollo\client\package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`****\node_modules\#apollo\client\main.cjs`. Indeed, none of these files exist:
Dependencies
"#apollo/client": "^3.3.2",
"graphql": "^15.4.0",
Anyone can help me please? Will be very thankful!
As documented at https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md#apollo-client-354-2021-11-19, the solution should be to add
const { getDefaultConfig } = require("metro-config");
const { resolver: defaultResolver } = getDefaultConfig.getDefaultValues();
exports.resolver = {
...defaultResolver,
sourceExts: [
...defaultResolver.sourceExts,
"cjs",
],
};
in your metro.config.js.
In my case, I already have a module.exports generated by default, so I just had to make the file so:
const {getDefaultConfig} = require('metro-config');
const {resolver: defaultResolver} = getDefaultConfig.getDefaultValues();
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
resolver: {
...defaultResolver,
sourceExts: [...defaultResolver.sourceExts, 'cjs'],
},
};
Simply adding cjs file extension to metro.config.js works for me.
According to expo's Official Adding more file extensions to assetExts documentation...
const { getDefaultConfig } = require('#expo/metro-config');
const defaultConfig = getDefaultConfig(__dirname);
defaultConfig.resolver.assetExts.push('cjs');
module.exports = defaultConfig;
I have exactly the same problem in react-native.
From the documentation, it follows that you need to add the ability to handle "cjs" files.
https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md#apollo-client-354-2021-11-19
Solved the problem today by adding to node_modules/metro-config/src/defaults/defaults.js
export.sourceExts = ["js", "json", "ts", "tsx", "cjs"];
and from the project folder
for android:
cd android && ./gradlew clean
for ios in xcode :
clean -> run
For Expo Projects, We need to add cjs to sourceExts.
const { getDefaultConfig } = require('#expo/metro-config');
const defaultConfig = getDefaultConfig(__dirname);
defaultConfig.resolver.sourceExts.push('cjs');
module.exports = defaultConfig;
Apollo Docs for source extension https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md#apollo-client-354-2021-11-19
Expo syntax for metro config https://docs.expo.dev/guides/customizing-metro/

Partially mock `react-native` module

I'm running unit tests in React Native that need the NativeEventEmitter and NativeModules mocked but leave everything else as passthrough to the real code.
This part seems to be working except when running I get this error.
Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'DevSettings' could not be found. Verify that a module by this name is registered in the native binary.
at invariant (../node_modules/invariant/invariant.js:40:15)
at Object.getEnforcing (../node_modules/react-native/Libraries/TurboModule/TurboModuleRegistry.js:39:3)
at Object.<anonymous> (../node_modules/react-native/Libraries/NativeModules/specs/NativeDevSettings.js:30:37)
at Object.<anonymous> (../node_modules/react-native/Libraries/Utilities/DevSettings.js:10:1)
Mocking:
jest.mock(
'react-native',
() => ({
...jest.requireActual('react-native'),
NativeEventEmitter: class MockNativeEventEmitter {
// ...
},
NativeModules: {
// ...
},
Platform: {
OS: 'android',
},
})
);
Online searches for this error all point to problems compiling in dev vs release mode, nothing remotely close to what I'm trying to do.
Have you tried importing DevSettings from react-native and adding the same imported module in your mock? This would be the process for every Component/Module being used in your tested component. Something like:
import { DevSettings } from 'react-native`
jest.mock(
'react-native',
() => ({
...jest.requireActual('react-native'),
NativeEventEmitter: class MockNativeEventEmitter {
// ...
},
NativeModules: {
// ...
},
Platform: {
OS: 'android',
},
DevSettings
})
);

Import monaco-editor using Vite 2

Currently, I have set up a Vite 2 project with monaco-editor as a dependency.
Whenever I am trying to use it says that the workers are not imported.
editorSimpleWorker.js:454 Uncaught (in promise) Error: Unexpected usage
at EditorSimpleWorker.loadForeignModule (editorSimpleWorker.js:454)
at webWorker.js:38
Since I am using Vite 2 I have assumed that simply specifying the rollup plugin rollup-plugin-monaco-editor in the plugins array. However, I am still getting this issue.
export default defineConfig({
plugins: [
vue(),
monaco({ languages: ['javascript'] }),
],
});
Is there any proper way to import monaco-editor into a Vite 2 project?
With the latest release (2.0.0-beta.59) it is fixed.
You can now add the environment workers without any further configuration (ref: https://github.com/vitejs/vite/discussions/1791)
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
self.MonacoEnvironment = {
getWorker(_, label) {
if (label === 'json') {
return new jsonWorker()
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new cssWorker()
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return new htmlWorker()
}
if (label === 'typescript' || label === 'javascript') {
return new tsWorker()
}
return new editorWorker()
}
}
The accepted answer is ok in dev build, but in production build at current version (v2.1.2), Uncaught ReferenceError: window is not defined is raised on page load.
So in addition to the accepted answer, build.rollupOptions.output.manualChunks needs to be added to vite.config.js like the following.
// vite.config.js
import { defineConfig } from 'vite';
const prefix = `monaco-editor/esm/vs`;
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
jsonWorker: [`${prefix}/language/json/json.worker`],
cssWorker: [`${prefix}/language/css/css.worker`],
htmlWorker: [`${prefix}/language/html/html.worker`],
tsWorker: [`${prefix}/language/typescript/ts.worker`],
editorWorker: [`${prefix}/editor/editor.worker`],
},
},
},
},
});

Unable to resolve module tensorflow_inception_graph.pb as a file nor as a folder

Here I am using tensor flow with react native using react-native-tensorflow llibrary. The library has installed properly. The code snippet which I am using and facing an issue is
const tfImageRecognition = new TfImageRecognition({
model: require('./assets/tensorflow_inception_graph.pb'),
labels: require('./assets/tensorflow_labels.txt'),
imageMean: 117, // Optional, defaults to 117
imageStd: 1 // Optional, defaults to 1 })
In the model property, when I am loading the tensorflow_inception_graph.pb file then it is giving me the error
error: bundling failed: UnableToResolveError: Unable to resolve module
`../asset/tensorflow_inception_graph.pb` from
`/Users/XYZ/App/code/Demo/src/ImageRecognitionAI.js`:
could not resolve `/Users/XYZ/App/code/Demo/src/assets/tensorflow_inception_graph.pb'
as a file nor as a folder
The file path which I am passing in model is checked and found correct. Can anyone help me to get out of this? Help will be appreciated.
place the tenserflow_labels.text and tensorflow_inception_graph.pb and file in the assets folder
=> android/app/src/main/assets/tensorflow_inception_graph.pb
=> android/app/src/main/assets/tenserflow_labels.text
now you can access it like this in your js file.
const tf = new TfImageRecognition({
model: 'file://tensorflow_inception_graph.pb',
labels: 'file://tenserflow_labels.txt'
});
it worked for me.
You have to specify the webpack type extensions in either the package or a rn-cli.config.js file. If you're using create-react-native-app then you want to add it to the app.json file like this:
{
"expo": {
"sdkVersion": "27.0.0",
"packagerOpts": {
"assetExts": ["pb", "txt"]
}
}
}
I didn't find that in the documentation for some reason, but I found it in some example projects.
If you're running your scripts with react-native start then you need to setup a rn-cli.config.js file. Here is the documentation
module.exports = {
getAssetExts() {
return ['pb', 'txt']
}
}
If you are running scripts from rn-cli.config.js
change file content to :
const { getDefaultConfig } = require("metro-config");
module.exports = (async () => {
const {
resolver: { assetExts }
} = await getDefaultConfig();
return {
resolver: {
assetExts: [...assetExts, "pb", "txt"]
}
};
})();