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

Posted

技术标签:

【中文标题】如何将 Relay 查询从 TypeScript 转换为 ES5?【英文标题】:How to transpile a Relay query from TypeScript to ES5? 【发布时间】:2016-04-21 07:30:56 【问题描述】:

我正在用 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 插件不再识别它们,所以它们不会被转译成浏览器可以理解的东西,所以浏览器会抛出错误:

未捕获的不变违规:RelayQL:意外调用 运行。要么未设置 Babel 变换,要么未设置 识别此呼叫站点。确保它被逐字用作 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 插件无法识别转换后的版本,因此它不会将查询转换为浏览器可以理解的内容。

如何做到这一点?

【问题讨论】:

【参考方案1】:

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

我建议使用 Webpack 来编排所有这些。这些将帮助您入门:

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

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

【讨论】:

太棒了。实际上,我的设置基于您提到的相同文章。但是因为我在 Node.js 中运行转译的 TypeScript(到 ES6)时遇到了 Mongoose 的问题,所以我将 tsconfig.json 更改为针对 ES5。现在我把浏览器改回 ES6(然后用 babel 改成 ES5),服务器改回 ES5。这样,它在浏览器和服务器上都可以工作。 如需更新的参考资料,请尝试artsy.github.io/blog/2017/11/27/Babel-7-and-TypeScript【参考方案2】:

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

    正确设置你的 babel-relay-plugin。如果您在这里遇到问题,我建议您使用 npm 包 babel-relay-plugin-loader,然后您可以在 package.json 中指定 schema.json 的位置。例如: "metadata": "graphql": "schema": "./schema.json"

    正确设置你的 babel 配置。它应该看起来像这样:

    “passPerPreset”:真, “预设”:[ “反应”, "es2015", “阶段 0” ], “插件”:[ “babel-relay-plugin-loader” ] ,

    将您的 tsconfig 设置为以“es6”为目标——这实际上对我的设置工作至关重要。 ts-loader 然后编译为 es6,Babel 将转译处理为 es5。

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

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

【讨论】:

【参考方案3】:

以防万一,当你说

我的 TypeScript 源代码使用 TypeScript 编译器 TSC 编译成 ES6 代码。然后,使用 Babel 将 ES6 代码转换为 ES5 代码。

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

【讨论】:

以上是关于如何将 Relay 查询从 TypeScript 转换为 ES5?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中使用 Relay Modern(babel-plugin-relay 和 relay-compiler)?

如何使用 Relay 发送临时查询?

如何使用带有 Typescript 的泛型将中继(graphql)连接映射到边缘节点

如何在用 TypeScript (TSX) 编写的 React 应用程序中使用 Facebook Relay?

GraphQL 类型在由 Relay 编译时在 Typescript 中被定义为未知

从外部存储中检索 Relay 查询片段的变量