Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to transpile a Relay query from TypeScript to ES5?

I'm writing a web app in TypeScript. The app uses React and Relay from Facebook. My TypeScript source code gets compiled into ES6 code using the TypeScript compiler TSC. Then, the ES6 code gets transpiled into ES5 code using Babel. In order for Relay to work in the browser, a Babel plugin needs to transform the Relay GraphQL queries: https://facebook.github.io/relay/docs/guides-babel-plugin.html. The problem is, because TSC first transpiles these queries, the Babel Relay plugin doesn't recognize them anymore so they don't get transpiled into something the browser understands, so the browser throws an error:

Uncaught 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.

My TypeScript source code:

const SiteQuery = {
    store: () => Relay.QL`query { site }`
};

... this gets compiled by TSC into something like this:

var SiteQuery = {\r\n    store: function () { return (_a = [\"query { site }\"], _a.raw = [\"query { site }\"], Relay.QL(_a)); var _a; }\r\n};

... instead of something like this (because the Babel Relay plugin doesn't do its work properly):

var SiteQuery = {\n    store: function store() {\n        return (function () {\n            return {\n                fieldName: 'site',\n                kind: 'Query',\n                metadata: {},\n                name: 'Router',\n                type: 'Site'\n            };

This is because the Babel Relay plugin doesn't recognize the transpiled version, and as a result it doesn't transpile the query into something the browser understands.

How to make this work?

like image 750
Korneel Avatar asked Jan 29 '26 01:01

Korneel


2 Answers

The answers here were helpful, but I thought I'd share what finally worked for me.

  1. Setup your babel-relay-plugin correctly. If you're running into problems here, I recommend using the npm package babel-relay-plugin-loader which then allows you to specify the location of your schema.json in package.json. For example: { "metadata": { "graphql": { "schema": "./schema.json" } } }
  2. Setup your babel config correctly. It should look something like this:

    { "passPerPreset": true, "presets": [ "react", "es2015", "stage-0" ], "plugins": [ "babel-relay-plugin-loader" ] } },

  3. Setup your tsconfig to target "es6" -- this actually was essential to make my setup work. ts-loader then compiles to es6 and Babel handles the transpile down to es5.

  4. Finally, add the loaders to your webpack config. Remember, it applies these RIGHT to left. So, mine looks like this:

    loaders: [ { test: /.tsx?$/, exclude: /node_modules/, loader: 'react-hot!babel!ts-loader', }, ],

like image 89
Matt Martin Avatar answered Jan 30 '26 17:01

Matt Martin


You need to tell the Typescript compiler to transpile to ES6, then use Babel with babel-relay-plugin and es2015 preset to transpile the code to ES5 to run in your browser.

I recommend using Webpack to orchestrate all this. These will get you started:

  1. http://www.jbrantly.com/typescript-and-webpack/
  2. http://www.jbrantly.com/es6-modules-with-typescript-and-webpack/

The posts were written for Babel 5.x, so you'll need to manually add es2015 preset to make sure Babel compiles the ES6 sources to ES6.

like image 31
Gunchars Avatar answered Jan 30 '26 17:01

Gunchars



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!