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

How to transpile a Relay query from TypeScript to ES5?

我正在用 TypeScript 编写网络应用程序。该应用程序使用来自 Facebook 的 React 和 Relay。 我的 TypeScript 源代码使用 TypeScript 编译器 TSC 编译成 ES6 代码。然后,使用 Babel 将 ES6 代码转换为 ES5 代码。为了让 Relay 在浏览器中工作,Babel 插件需要转换 Relay GraphQL 查询:https://facebook.github.io/relay/docs/guides-babel-plugin.html。问题是,因为 TSC 首先转换这些查询,Babel Relay 插件不再识别它们,所以它们不会被转换成浏览器理解的东西,所以浏览器抛出错误:

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.

我的 TypeScript 源代码:

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

...这被 TSC 编译成这样的东西:

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

... 而不是像这样的东西(因为 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            };

这是因为 Babel Relay 插件无法识别转换后的版本,因此它无法将查询转换为浏览器可以理解的内容。

如何进行这项工作?

您需要告诉 Typescript 编译器转译为 ES6,然后在浏览器中使用带有 babel-relay-plugines2015 预设的 Babel 将代码转译为 ES5 到 运行。

我推荐使用 Webpack 来协调这一切。这些将帮助您入门:

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

帖子是为 Babel 5.x 编写的,因此您需要手动添加 es2015 预设以确保 Babel 将 ES6 源代码编译为 ES6。

这里的答案很有帮助,但我想我会分享最终对我有用的东西。

  1. 正确设置你的 babel-relay-plugin。如果你 运行 在这里遇到问题,我建议使用 npm 包 babel-relay-plugin-loader,它允许你在 package.json 中指定你的 schema.json 的位置。例如: { "metadata": { "graphql": { "schema": "./schema.json" } } }
  2. 正确设置你的 babel 配置。它应该看起来像这样:

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

  3. 将您的 tsconfig 设置为目标 "es6"——这实际上对于使我的设置工作至关重要。 ts-loader 然后编译为 es6,Babel 将转译文件处理为 es5。

  4. 最后,将加载程序添加到您的 webpack 配置中。请记住,它将这些 RIGHT 应用于 left。所以,我的看起来像这样:

    装载机:[ { 测试:/.tsx?$/, 排除:/node_modules/, 装载机:'react-hot!babel!ts-loader', }, ],

以防万一,当你说

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.

您可以指示 TypeScript 本身直接转译为 es5,只需在 tsconfig.json 中设置 target: 'es5' 即可,希望对您有所帮助,因为您可以从编译链中删除 babel。