如何在 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 之谜