我已经将此作为问题发布在 graphql-tag 存储库中,但我会将其发布在这里,因为我希望这里有人有一个可行的解决方案。
我想做什么?
我想根据传递给我的反应组件的道具动态定义本地类型的 typedef。
我为什么要这样做?
我意识到这不是定义 gql 的预期方式,但是,我正在围绕 Apollo Provider 创建一个 React 包装器组件。它的目的是使本地模拟数据的过程(如此处所述https://www.apollographql.com/docs/react/development-testing/client-schema-mocking/)更加无缝且样板更少。我将采用一种声明性方法,用户可以简单地定义一个字段数组(名称、graphQL 类型和可选实现,默认为 graphQL 类型的合理伪造实现),这将使本地字段直接在 Query 类型上可用以及一个类型数组(名称、字段和可选的嵌套类型),它们应该可以在没有样板的情况下以声明方式定义任意本地模式。
目前的结果是什么?
只是为了建立一个基线,以下工作正常,并允许我从 Apollo CLI 运行代码生成并在我的应用程序中查询新的本地测试字段(使用 @client 指令)
const localTypeDefs = gql`
extend type Query {
test: String
}
`;
const client = new ApolloClient({
cache: new InMemoryCache(),
uri: "https://localhost:4000/graphql",
typeDefs: localTypeDefs,
...apolloClientOptions,
});
如果我将 qgl 定义更改为如下所示
const name = "name";
const graphQLType = "String";
const localTypeDefs = gql`
extend type Query {
${name}: ${graphQLType}
}
`;
运行 codegen 时出现以下错误Syntax Error: Expected Name, found ":"
。如果我将 gql 定义更改为此
const testString = "test: String";
const localTypeDefs = gql`
extend type Query {
${testString}
}
`;
Syntax Error: Expected Name, found "}".
我在 codegen 上收到此错误。通常,似乎插值字符串之后的所有内容都会导致编译器在下一个字符上发出此错误。如果我}
在 testString 中包含 ,我会得到错误Syntax Error: Expected Name, found <EOF>.
。
现在,如果我尝试更改为函数语法,那么 localTypeDefs 定义如下所示:
const testString = "test: String";
const localTypeDefs = gql(`extend type Query { ${testString} } `);
typedef 实际上是在没有任何错误的情况下生成的,但是,GraphQLError: Cannot query field "test" on type "Query"
当我查询该字段时,代码生成仍然失败并出现错误。与我在顶部发布的工作基线相比,该查询根本没有改变,如果我在不触及任何其他内容的情况下改回该基线,则代码生成器不再抱怨该查询。奇怪的是,如果我将上面的内容改回基线实现,但保留显式函数调用而不是隐式 `` 字符串,如下所示:
const localTypeDefs = gql(`
extend type Query {
test: String
}
`);
我仍然收到错误消息GraphQLError: Cannot query field "test" on type "Query"
,但是一旦我改回基本情况,一切正常。