Invariant Violation when upgrading React Native and dependencies - javascript

It's been a while since I updated my React Native project dependancies, and I'm trying to bring everything up to date. I started on react-native#0.42.0 and react#15.4.1. I updated everything using npm install --save react-native#x.x.x.
Now that I've updated everything, I can't get my app to run. I'm getting the following error:
Invariant Violation: Element type is invalid: expected a strong (for built-in components) or a class/function (for composite components) but got:object
As a last ditch effort to debug, I've done the following:
Commented out all application code so the only code running is inside index.android.js:
import { AppRegistry } from 'react-native'
import CRV from './app'
AppRegistry.registerComponent('CRV', () => CRV)
Modified my packages.json file so that only react and react-native are loading:
"dependencies": {
"react": "^16.0.0-beta.5",
"react-native": "^0.49.1"
}
When I run my app, I'm getting the red screen:
Unfortunately, I have no idea how to proceed at this point. Perhaps I've commented out too much and there's some other code I need to let run before trying to isolate the problem?

Unfortunately the answer isn't very glamorous.
Fortunately I was doing all my work on a branch. I had used react-native upgrade originally, and that's what lead me to this fail.
I finally destroyed that branch and got my environment back up on 0.42.0. I then used the new react-native-git-upgrade (docs). It was still a very tedious process, but once I updated all my other dependencies and fixed issues in my code related to requirements from the upgrade, it worked.

Related

Cannot import Tone.js is in a Next.js project

I'm unable to import Tone in my Next.js project. I have Tone as a dependency, but when I run import * as Tone from 'tone' Next says it can't find the module node_modules/tone/build/esm/core/Global imported from node_modules/tone/build/esm/index.js. Originally I thought it was a browser thing, where I had to make sure I was importing Tone only in the browser and not in Node, but dynamically importing (as described here) in the useEffect hook (which only runs in the browser), but it still couldn't find the module.
The odd thing is that the browser console prints * Tone.js v14.8.38 *, so clearly Tone exists, but Next can't find it for some reason.
I'm running Next.js version 12, Tone v14.8.38, React 18 and yarn v3.2.0, if that matters. I'd really appreciate any help!
You are on the right track with the dynamic loading, I've got a large project doing it that way. This is how I've done it (although I can't really see what you have done wrong) -
const DynamicComponent = dynamic(
() => import('../components/foobar'),
{ ssr: false }
)
More details can be seen here (although I see you posted that already).
https://nextjs.org/docs/advanced-features/dynamic-import
Inside your component you can import tone objects in the following fashion eg.
import { Clock, Merge, Oscillator, Player, Waveform } from "tone";
I have used useEffect to instantiate tone classes, but I have also done it using JS classes. Both ways worked for me.
Is this different from what you did? Just to check you are doing the dynamic import at the page level right? And how are you importing the tone objects? This depends on your specific code.
I'm using
"next": "^10.0.9",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"tone": "^14.7.77"
Might be worth downgrading to these and trying.
it is currently not possible to run tone in node. You should download tone.js from here and include it as a script in your project.
you could also try using another library like soundfont

How to configure babel for react-relay (classic) on react-native 0.57+

I've been trying to upgrade react-native for our app from 0.52.0 to latest since 4th of january.
Up to 0.55.0 everything went fine (had some issues with 0.56.0 cause react-native-router-flux were incompatible), but when trying to go to 0.57.0 everything stopped working.
After fixing all other errors, no matter what I do I get this error:
Invariant Violation: RelayQL: Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify this call site. Make sure it is being used verbatim as `Relay.QL`.
This error is located at:
in RelayRenderer (at TabIcon.js:77)
in TabIcon (at navigationStore.js:245)
in RCTView (at View.js:44)
in AnimatedComponent (at CrossFadeIcon.js:34)
in RCTView (at View.js:44)
in TabBarIcon (at BottomTabBar.js:142)...etc
(Btw: It's nothing special about that particular relay container; whatever container wrapped with a Relay.Renderer is called first will fail with the same error.)
As my code definitely uses verbatim Relay.QL in the relevant code, the issue obviously must be that the babel transform isn't working.
The old .babelrc that worked at least up to react-native 0.55.0:
{
"presets": [
"react-native",
{
"plugins": ["custom-relay"]
}
]
}
The custom-relay is a small script that a previous developer copied from somewhere:
const getBabelRelayPlugin = require('babel-relay-plugin');
const schema = require('../../schema.json');
module.exports = getBabelRelayPlugin(schema.data);
After a few days of swearing I realized that even though the documentation and the react-native-git-upgrade script tells me to upgrade the .babelrc file; it appears that this file is completely ignored, so when I moved the config to a babel.config.js file instead at least I started getting new errors indicating that this file were used.
The custom-relay script turned out to be impossible to translate into something that is compatible with babel 7 since the deprecated babel-relay-plugin doesnt work with babel 7 and babel-plugin-relay doesn't export the correct methods; besides it's supposed to work without it now.
My current babel.config.js:
module.exports = function babelconfig(api) {
api.cache(false);
return {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
['relay', { compat: true, schema: 'schema.json' }],
'#babel/transform-runtime',
],
};
};
I've also changed the .babelrc file to say the same (only in JSON syntax) for good measure, but it doesn't help.
Googling for this issue has been fruitless so far, the only issues and SO questions I've found seems to be related to older versions of react-native (or just react) and the solutions are generally variants of the old .babelrc config that no longer works such as (2206, 1202, 2025, 1899). And I've been unable to find any babel config examples that both uses react-native 0.57.0 and babel 7 syntax as well as react-relay.
I once found a forum post or issue where someone mentioned something to indicate that migrating from Relay Classic to Relay Modern would work; but I can't remember where I found it; and since this migration is a massive undertaking in itself I'm not very eager to start doing that just to discover that the error message just changes from RelayQL: Unexpected invocation at runtime. to graphql: Unexpected invocation at runtime.
But if someone can confirm (with sources) that either react-native 0.57+ or babel 7 is definitely incompatible with relay classic syntax, and that migrating to modern will solve all my issues; of course I will do so.
I figured it out myself...
Seems the issue was caused by incomplete documentation about how to use Relay Classic with newer versions. I've created an issue for this here.
If you're having the same issue as me, you're probably also using the "wrong" variable name Relay rather than RelayClassic when importing from react-relay/classic like me.
I changed:
import Relay from 'react-relay/classic';
//...
fragments: {
viewer: () => Relay.QL`
to:
import RelayClassic from 'react-relay/classic';
//...
fragments: {
viewer: () => RelayClassic.QL`
everywhere. And suddenly it started working again.

prevent importing non existing node modules

I'm using React Native, npm, node v 8.9.4, eslint.
If I import View from 'View', my app simply takes View from 'react-native' and works (like it does when I use the proper form import { View } from 'react-native'). But in production (where different versions of node and different build processes may exist), it crashes on this.
I rather have it throw an error right away if I try to import something in this way, rather than some system trying to be smart about it. I want to have either node, eslint, or some other system warn me about this kind of import.
How can I make sure that importing from a non-existing node module simply throws an error, instead of trying to be smart about it?

Ember load-initializers error: Could not find module `ember-load-initializers`

I'm having trouble updating an older Ember app.
I've ported the code into a new, empty ember app and installed the dependencies. I get no error when I serve the app, but when I inspect the browser console, I see that the app failed to launch.
Uncaught Error: Could not find module `ember/load-initializers` imported from `<my-app>/app`
I've seen a similar SO post that suggested this was caused by issues with ember-cli and jquery. link
However, that post is over a year old and I'm running an up-to-date version of ember along with an newer jquery library. Sure, it's no guarantee, but it seems a bit unlikely that this is still an issue for ember-cli.
My app/app.coffee file is pretty basic (no additions)
`import Ember from 'ember'`
`import Resolver from 'ember/resolver'`
`import loadInitializers from 'ember/load-initializers'`
`import config from './config/environment'`
Ember.MODEL_FACTORY_INJECTIONS = true
App = Ember.Application.extend
modulePrefix: config.modulePrefix
podModulePrefix: config.podModulePrefix
Resolver: Resolver
loadInitializers(App, config.modulePrefix)
`export default App`
From the console, I can verify that my app is using the expected jquery version:
$ Ember.$.fn.jquery
"3.2.0"
However, from the command line, I get a different version.
$ bower jquery -v
1.8.0
I'm not sure whether that's meaningful or a red herring.
At any rate, my ember-cli is fairly recent.
ember-cli: 2.12.0
I've added links to the package.json and bower.json files, in case they contain any clues.
At this point, I'm not really sure how to troubleshoot the issue. The depency
import Resolver from './resolver'
import loadInitializers from 'load-initializers'
Update those line app.js file and try it
If you haven't done this already, in the app.js, switch
import loadInitializers from 'ember/load-initializers'
over to
import loadInitializers from 'ember-load-initializers'
they changed the naming conventions of loadInitializers recently.

Why does my `react-scripts` test not recognize the Jest function `toMatchObject`?

I am testing a React app, having essentially followed the standard, officially-blessed create-react-app setup.
I have written my test as follows:
import React from 'react';
import {shallow} from 'enzyme';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('should have the expected properties', () => {
const wrapper = shallow(<MyComponent/>);
expect(wrapper.props()).toMatchObject({a: 1});
});
});
My package.json contains the following:
{
...
"devDependencies": {
"enzyme": "^2.6.0",
"react-scripts": "0.8.3",
...
},
"dependencies": {
"react": "^15.4.1",
...
},
"scripts": {
"test": "react-scripts test --env=jsdom",
...
},
"jest": {
"automock": false
}
}
When I run the tests I get the following error message: TypeError: expect(...).toMatchObject is not a function.
However, the react-scripts documentation states that Jest is one of the built-in tools used, e.g. I don't have to npm install it. And the Jest documentation clearly shows that toMatchObject is a function.
So why do I get this error message?
tl;dr: Run npm install jest to get the latest (v18+) jest.
Original answer in early Dec 2016:
I have discovered that this is an issue with Jest itself. It is documented here. If I read it correctly, it's not so much a bug as it is a feature-in-the-works that made its way into the documentation before it was actually ready for public release. Apparently, it should be coming out any day now. In the mean time, someone (the Jest team? someone else?) has provided a helper which can be found here to fill in for this matcher until its officially available. I haven't actually tried this helper, and I suspect it might disappear soon, but I thought I'd let any interested readers know about it if they really want this feature.
Update in early January 2017:
According to this website the toMatchObject matcher was included in Jest on approximately Jan 3, 2017. That was for Jest v18 (18.0.0? ... it's currently at 18.1.0). This was still not included in the basic React download, as this matcher still did not work for me when I deleted my node_modules folder and re-npm install-ed everything. However, if I specifically updated jest with npm install jest then node_modules/jest/package.json indicated that jest was now updated (for me on Jan 15, 2017, updated to version 18.1.0) and toMatchObject now seems to work.
...Actually, the solution in the above paragraph seems fickle, as it did work when I initially used it, but then stopped working again shortly after that (after again re-deleting node_modules, re-npm installing everything, re-doing npm install jest, and even trying #Scimonster's suggestion from the comments, i.e. deleting node_modules/react-scripts/node_modules/jest). I did find another working hack: manually adding the actual toMatchObject code from here to node_modules/react-scripts/node_modules/jest-matchers/build/matchers.js (after reverting some ES6/typescript/babel?-ish syntax). I presume this will all be fixed in a not-too-far-in-the-future update to React, but for now this works for me (at least for the moment!).

Categories

Resources