We're beginning incremental conversion of our app to Relay Modern. After converting one mutation, the babel plugin isn't converting the graphql calls, giving us "graphql: Unexpected invocation at runtime." The Relay Compiler is also not generating any of the expected side files. Relay.QL calls are properly converted.
We've read the Plugin and Compat instructions carefully several times and reinstalled babel-plugin-relay@dev. Debug mode is set in the plugin; unfortunately the plugin and relay compiler are black boxes to us and not outputting much info, so there doesn't appear to be a way for us to debug this.
It looks to me like the "compat": true flag isn't working because only Relay Classic calls are converted. Is something broken here or are we missing some lynchpin?
More info:
.babelrc:
{
"presets": [
{
"plugins": [
["relay", {"compat": true, "schema": "./schema.graphql", "debug": true}]
]
},
"react-native"
]
}
Running babel gives us final .js code like this, still with a .graphql call:
var mutation = compat_1.graphql(_templateObject2);
relay-compiler gives this output and does nothing:
Parsed default in 0.07s
Writing default
Writer time: 0.05s [0.04s compiling, 0.00s generating, 0.00s extra]
Unchanged: 0 files
Written default in 0.06s
Thank you - other than this, the Relay Modern looks much cleaner and more pleasurable to use.
This issue was related to using TypeScript with Relay. We were using this import:
import { commitMutation, graphql } from 'react-relay/compat';
Which was outputting JS like const mutation = compat_.graphql.... It looks like both relay-compiler and babel-plugin-react expect bare graphql calls; if graphql is called as a method on an object like this, it won't be parsed.
Our fix is to use old-style require like this:
const { commitMutation, graphql } = require('react-relay/compat');
This outputs bare graphql calls and works perfectly.
I had this problem using ts-loader in webpack, and managed to fix it by disabling typescript transpiling (and instead letting babel handle it):
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: {
compilerOptions: {
target: 'ESNEXT'
}
},
exclude: /node_modules/,
},
@miracle2k I like your solution better as it allows us to use standard module import syntax everywhere. We've implemented this.
We also needed to use tsconfig.json "module": "es2015" and "allowSyntheticDefaultImports": true for use with a couple of our libraries (Moment and Auth0 React Native Lock).
Moment import now looks like
import Moment from 'moment';
No more old "require" statements.
Feel free to post the solution here and I'll mark as the accepted answer:
https://stackoverflow.com/questions/44004135/how-to-use-relay-modern-babel-plugin-relay-and-relay-compiler-with-typescript
Most helpful comment
I had this problem using ts-loader in webpack, and managed to fix it by disabling typescript transpiling (and instead letting babel handle it):