How to transpile a Relay query from TypeScript to ES5?

自闭症网瘾萝莉.ら 提交于 2020-01-04 02:19:08

问题


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?


回答1:


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.




回答2:


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', }, ],




回答3:


Just in case, when you say

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.

You can instruct TypeScript itself to transpile directly to es5, just set target: 'es5' in tsconfig.json and that's it, hope it helps since you can eliminate babel from your compile chain.



来源:https://stackoverflow.com/questions/34815578/how-to-transpile-a-relay-query-from-typescript-to-es5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!