如何在 react-native 0.57+ 上为 react-relay(经典)配置 babel

Posted

技术标签:

【中文标题】如何在 react-native 0.57+ 上为 react-relay(经典)配置 babel【英文标题】:How to configure babel for react-relay (classic) on react-native 0.57+ 【发布时间】:2019-06-18 06:20:36 【问题描述】:

自 1 月 4 日以来,我一直在尝试将我们应用的 react-native 从 0.52.0 升级到最新版本。

到 0.55.0 一切正常(0.56.0 出现一些问题,导致 react-native-router-flux 不兼容),但是当尝试转到 0.57.0 时,一切都停止了。

修复所有其他错误后,无论我做什么,我都会收到此错误:

不变违规:RelayQL:运行时意外调用。要么未设置 Babel 转换,要么未能识别此调用站点。确保它被逐字用作`Relay.QL`。 此错误位于: 在 RelayRenderer 中(在 TabIcon.js:77) 在 TabIcon 中(在 navigationStore.js:245) 在 RCTView 中(在 View.js:44) 在 AnimatedComponent 中(在 CrossFadeIcon.js:34) 在 RCTView 中(在 View.js:44) 在 TabBarIcon 中(位于 BottomTabBar.js:142)...等

(顺便说一句:那个特定的中继容器没有什么特别之处;任何用 Relay.Renderer 包装的容器首先被调用都会失败并出现同样的错误。)

由于我的代码在相关代码中绝对逐字使用Relay.QL,问题显然一定是 babel 转换不起作用。

旧的 .babelrc 至少可以工作到 react-native 0.55.0:


  "presets": [
    "react-native",
    
      "plugins": ["custom-relay"]
    
  ]

自定义中继是以前的开发人员从某处复制的小脚本:

const getBabelRelayPlugin = require('babel-relay-plugin');
const schema = require('../../schema.json');

module.exports = getBabelRelayPlugin(schema.data);

经过几天的宣誓后,我意识到即使文档和react-native-git-upgrade 脚本告诉我升级 .babelrc 文件;看来这个文件被完全忽略了,所以当我将配置移动到 babel.config.js 文件时,至少我开始收到新的错误,表明这个文件被使用了。

由于已弃用的 babel-relay-plugin 不适用于 babel 7 并且 babel-plugin-relay 无法导出正确的方法,因此自定义中继脚本无法转换为与 babel 7 兼容的内容;除了它现在应该在没有它的情况下工作。

我目前的 babel.config.js:

module.exports = function babelconfig(api) 
  api.cache(false);
  return 
    presets: ['module:metro-react-native-babel-preset'],
    plugins: [
      ['relay',  compat: true, schema: 'schema.json' ],
      '@babel/transform-runtime',
    ],
  ;
;

我也将 .babelrc 文件更改为相同的内容(仅在 JSON 语法中),但这并没有帮助。

到目前为止,谷歌搜索这个问题没有结果,我发现的唯一问题和 SO 问题似乎与旧版本的 react-native(或只是反应)有关,并且解决方案通常是旧 .babelrc 的变体不再起作用的配置,例如(2206、1202、2025、1899)。而且我找不到任何同时使用 react-native 0.57.0 和 babel 7 语法以及 react-relay 的 babel 配置示例。

我曾经发现一个论坛帖子或问题,其中有人提到某些内容表明从 Relay Classic 迁移到 Relay Modern 是可行的;但我不记得我在哪里找到的;由于这次迁移本身就是一项艰巨的任务,我并不急于开始这样做,只是为了发现错误消息只是从 RelayQL: Unexpected invocation at runtime. 更改为 graphql: Unexpected invocation at runtime

但是如果有人可以(通过消息来源)确认 react-native 0.57+ 或 babel 7 肯定与中继经典语法不兼容,那么迁移到现代将解决我所有的问题;我当然会这样做。

【问题讨论】:

【参考方案1】:

我自己想通了...... 似乎该问题是由有关如何将 Relay Classic 与较新版本一起使用的文档不完整引起的。 I've created an issue for this here.

如果你和我有同样的问题,你可能也像我一样从 react-relay/classic 导入时使用了“错误的”变量名 Relay 而不是 RelayClassic

我变了:

import Relay from 'react-relay/classic';
//...
fragments: 
      viewer: () => Relay.QL`

收件人:

import RelayClassic from 'react-relay/classic';
//...
fragments: 
      viewer: () => RelayClassic.QL`

无处不在。突然它又开始工作了。

【讨论】:

以上是关于如何在 react-native 0.57+ 上为 react-relay(经典)配置 babel的主要内容,如果未能解决你的问题,请参考以下文章

react-native 0.57 run-ios 失败解决办法

React-Native Metro 捆绑器无法提供任何文件

React Native 在 iOS 上为 addImageFromBase64 指定文件格式

0.57 * 100 === 56.99999999999999 之谜

使 react-native run-android 命令在编译项目时不下载文件

使用ClojureScript,Re-natal和React-Native禁用RTL?