简体   繁体   English

如何将Relay查询从TypeScript转换为ES5?

[英]How to transpile a Relay query from TypeScript to ES5?

I'm writing a web app in TypeScript. 我正在用TypeScript编写一个Web应用程序。 The app uses React and Relay from Facebook. 该应用程序使用Facebook的React和Relay。 My TypeScript source code gets compiled into ES6 code using the TypeScript compiler TSC. 我的TypeScript源代码使用TypeScript编译器TSC编译成ES6代码。 Then, the ES6 code gets transpiled into ES5 code using Babel. 然后,使用Babel将ES6代码转换为ES5代码。 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 . 为了让Relay在浏览器中工作,Babel插件需要转换Relay GraphQL查询: 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: 问题是,因为TSC首先转发这些查询,所以Babel Relay插件不再识别它们,因此它们不会被转换成浏览器理解的内容,因此浏览器会抛出错误:

Uncaught Invariant Violation: RelayQL: Unexpected invocation at runtime. Uncaught Invariant Violation:RelayQL:运行时意外调用。 Either the Babel transform was not set up, or it failed to identify this call site. 未设置Babel转换,或者无法识别此呼叫站点。 Make sure it is being used verbatim as Relay.QL . 确保它被逐字地用作Relay.QL

My TypeScript source code: 我的TypeScript源代码:

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

... this gets compiled by TSC into something like this: ...这由TSC编译成如下:

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): ...而不是像这样的东西(因为Babel Relay插件不能正常工作):

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. 这是因为Babel Relay插件无法识别转换后的版本,因此它不会将查询转换为浏览器理解的内容。

How to make this work? 如何使这项工作?

The answers here were helpful, but I thought I'd share what finally worked for me. 这里的答案很有帮助,但我想我会分享最终对我有用的东西。

  1. Setup your babel-relay-plugin correctly. 正确设置你的babel-relay-plugin。 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. 如果您遇到问题,我建议使用npm软件包babel-relay-plugin-loader ,然后允许您在package.json中指定schema.json的位置。 For example: { "metadata": { "graphql": { "schema": "./schema.json" } } } 例如: { "metadata": { "graphql": { "schema": "./schema.json" } } }
  2. Setup your babel config correctly. 正确设置您的babel配置。 It should look something like this: 它应该看起来像这样:

    { "passPerPreset": true, "presets": [ "react", "es2015", "stage-0" ], "plugins": [ "babel-relay-plugin-loader" ] } }, {“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. 设置你的tsconfig以“es6”为目标 - 这实际上对我的设置工作至关重要。 ts-loader then compiles to es6 and Babel handles the transpile down to es5. ts-loader然后编译成es6,Babel处理transale到es5。

  4. Finally, add the loaders to your webpack config. 最后,将加载器添加到webpack配置中。 Remember, it applies these RIGHT to left. 请记住,它将这些权利适用于左派。 So, mine looks like this: 所以,我的看起来像这样:

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

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. 您需要告诉Typescript编译器转换为ES6,然后使用Babel与babel-relay-plugines2015预设将代码转换为ES5以在浏览器中运行。

I recommend using Webpack to orchestrate all this. 我建议使用Webpack来协调所有这些。 These will get you started: 这些将帮助您入门:

  1. http://www.jbrantly.com/typescript-and-webpack/ http://www.jbrantly.com/typescript-and-webpack/
  2. http://www.jbrantly.com/es6-modules-with-typescript-and-webpack/ 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. 帖子是为Babel 5.x编写的,因此您需要手动添加es2015预设,以确保Babel将ES6源编译为ES6。

Just in case, when you say 以防万一,当你说

My TypeScript source code gets compiled into ES6 code using the TypeScript compiler TSC. 我的TypeScript源代码使用TypeScript编译器TSC编译成ES6代码。 Then, the ES6 code gets transpiled into ES5 code using Babel. 然后,使用Babel将ES6代码转换为ES5代码。

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. 您可以指示TypeScript本身直接转换为es5,只需在tsconfig.json中设置target:'es5'即可,希望它有所帮助,因为您可以从编译链中消除babel。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM