Search code examples
reactjstypescriptrelayjsrelaymodern

relay-compiler unable to extract and use graphql queries in Typescript


I tried using relay with the Typescript react starter, and am running into multiple issues.

Seems like babel-plugin-relay is not able to sense the graphql statements extracted by the relay-compiler. Here is my compiler script

"relay": "relay-compiler --src ./src --schema ./src/schema.graphql --extensions=tsx --watchman false".

.babelrc

{
   "babel": {
   "presets": [
      "react-app"
   ],
   "plugins": [
     "relay"
   ]
}

This is my error which suggests an issue with babel transpilation

graphql: 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 `graphql`.

Solution

  • Essentially the problem resolves around pulling out the GraphQL tags from typescript during transformations. I figured out the solution thanks to work in these PRs #1710 and #2293.

    Here are the steps:

    Modify the webpack config to include a babel loader (the typescript starter only has a ts-loader).

        ...
        test: /\.(ts|tsx)$/,
        include: paths.appSrc,
        exclude: /node_modules/,
        use: [
           { loader: 'babel-loader' },
           {
             loader: require.resolve('ts-loader'),
             options: {
                transpileOnly: true,
             },
           },
        ],
        ...
    

    Change the target and module configuration in tsconfig to es2015

    ...
    "target": "es2015",
    "module": "es2015",
    ...
    

    Add relay-compiler-language-typescript

    yarn add relay-compiler-language-typescript -D
    

    Also add babel-plugin-transform-es2015-modules-commonjs.

    yarn add babel-plugin-transform-es2015-modules-commonjs -D
    

    Since now we are targetting es2015, this plugin is needed to support ES module import and export statements.

    And a script to compile graphql statements

    "relay": "relay-compiler --src ./src --schema src/schema.graphql --language typescript --artifactDirectory ./src/__generated__ --watch"
    

    Point the relay plugin to use the artifacts generated by the above command in .babelrc

    "plugins": [
        "transform-es2015-modules-commonjs",
        ["relay", { "artifactDirectory": "./src/__generated__" }],
     ],