Graphql 需要模块外部与内部 GraphQLObjectType
Graphql requiring module outside vs inside GraphQLObjectType
可能标题不适合我的问题,但让我解释一下我的情况。
我正在使用 Graphql schema.Here 是我的初始 schema.js 文件 https://github.com/sany2k8/graphql-udemy/blob/master/schema/schema.js
它运行良好,然后我决定将它分成不同的小文件,例如 root_query_type.js、mutation.js、user_type.js 和 company_type.js。所有文件都作为模块导出并循环需要。例如 -
user_type.js
const graphql = require('graphql');
const axios = require('axios');
const { GraphQLObjectType, GraphQLString, GraphQLInt } = graphql;
//const CompanyType = require('./company_type'); // *this line causing error*
const UserType = new GraphQLObjectType({
name: "User",
fields: () => ({
id:{ type: GraphQLString},
firstName:{ type: GraphQLString},
age:{ type: GraphQLInt},
company :{
type: require('./company_type'), // *this line fix the error*
resolve(parentValue, args){
return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
.then(res => res.data)
}
}
})
});
module.exports = UserType;
company_type.js
const graphql = require('graphql');
const axios = require('axios');
const { GraphQLObjectType, GraphQLString, GraphQLList } = graphql;
const UserType = require('./user_type');
const CompanyType = new GraphQLObjectType({
name: "Company",
fields: ()=> ({
id: { type: GraphQLString},
name: { type: GraphQLString},
description: { type: GraphQLString},
users:{
type: new GraphQLList(UserType),
resolve(parentValue, args){
return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`)
.then(res => res.data)
}
}
})
});
module.exports = CompanyType;
在我的 user_type.js 文件上,当我在文件顶部使用 const CompanyType = require('./company_type');
时,像这样 const UserType 它显示下面的错误消息
Error: User.company field type must be Output Type but got: [object
Object].
但是如果我把那行注释掉并直接放上去就可以了。
company :{
type: require('./company_type'),
resolve(parentValue, args){
return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
.then(res => res.data)
}
}
所以基本上我的问题是为什么它不能与 const CompanyType = require('./company_type');
一起使用而与 type: require('./company_type')
一起使用。我可能是一个简单的逻辑问题,但它无法 find.Please 帮助我。
您看到的行为并非特定于 GraphQL,而是一般节点。您的模块中存在循环依赖性,这导致 user_type.js
中的 require
语句解析为 company_type.js
.
的不完整副本
According to the docs,给定两个相互需要的模块(a.js
和 b.js
):
When main.js
loads a.js
, then a.js
in turn loads b.js
. At that point,
b.js
tries to load a.js
. In order to prevent an infinite loop, an
unfinished copy of the a.js
exports object is returned to the b.js
module. b.js
then finishes loading, and its exports
object is provided
to the a.js
module.
在导出定义中移动 require 语句是一种解决方案。您还可以将您的导出定义 移动到 上方 您的 require 调用以获得相同的效果。 This question 更深入地研究循环依赖并提供一些替代解决方案。
附带说明一下,这是我建议不要以编程方式声明 GraphQL 模式的原因之一。您可以使用 graphql-tools
的 generate-schema 从 GraphQL 语言文档生成模式。这可以防止您处理潜在的循环依赖关系并产生更具可读性的模式。您也可以轻松地将模式模块化;您的类型定义只是字符串,您的解析器只是对象——两者都可以轻松组合。
可能标题不适合我的问题,但让我解释一下我的情况。 我正在使用 Graphql schema.Here 是我的初始 schema.js 文件 https://github.com/sany2k8/graphql-udemy/blob/master/schema/schema.js
它运行良好,然后我决定将它分成不同的小文件,例如 root_query_type.js、mutation.js、user_type.js 和 company_type.js。所有文件都作为模块导出并循环需要。例如 -
user_type.js
const graphql = require('graphql');
const axios = require('axios');
const { GraphQLObjectType, GraphQLString, GraphQLInt } = graphql;
//const CompanyType = require('./company_type'); // *this line causing error*
const UserType = new GraphQLObjectType({
name: "User",
fields: () => ({
id:{ type: GraphQLString},
firstName:{ type: GraphQLString},
age:{ type: GraphQLInt},
company :{
type: require('./company_type'), // *this line fix the error*
resolve(parentValue, args){
return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
.then(res => res.data)
}
}
})
});
module.exports = UserType;
company_type.js
const graphql = require('graphql');
const axios = require('axios');
const { GraphQLObjectType, GraphQLString, GraphQLList } = graphql;
const UserType = require('./user_type');
const CompanyType = new GraphQLObjectType({
name: "Company",
fields: ()=> ({
id: { type: GraphQLString},
name: { type: GraphQLString},
description: { type: GraphQLString},
users:{
type: new GraphQLList(UserType),
resolve(parentValue, args){
return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`)
.then(res => res.data)
}
}
})
});
module.exports = CompanyType;
在我的 user_type.js 文件上,当我在文件顶部使用 const CompanyType = require('./company_type');
时,像这样 const UserType 它显示下面的错误消息
Error: User.company field type must be Output Type but got: [object Object].
但是如果我把那行注释掉并直接放上去就可以了。
company :{
type: require('./company_type'),
resolve(parentValue, args){
return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
.then(res => res.data)
}
}
所以基本上我的问题是为什么它不能与 const CompanyType = require('./company_type');
一起使用而与 type: require('./company_type')
一起使用。我可能是一个简单的逻辑问题,但它无法 find.Please 帮助我。
您看到的行为并非特定于 GraphQL,而是一般节点。您的模块中存在循环依赖性,这导致 user_type.js
中的 require
语句解析为 company_type.js
.
According to the docs,给定两个相互需要的模块(a.js
和 b.js
):
When
main.js
loadsa.js
, thena.js
in turn loadsb.js
. At that point,b.js
tries to loada.js
. In order to prevent an infinite loop, an unfinished copy of thea.js
exports object is returned to theb.js
module.b.js
then finishes loading, and itsexports
object is provided to thea.js
module.
在导出定义中移动 require 语句是一种解决方案。您还可以将您的导出定义 移动到 上方 您的 require 调用以获得相同的效果。 This question 更深入地研究循环依赖并提供一些替代解决方案。
附带说明一下,这是我建议不要以编程方式声明 GraphQL 模式的原因之一。您可以使用 graphql-tools
的 generate-schema 从 GraphQL 语言文档生成模式。这可以防止您处理潜在的循环依赖关系并产生更具可读性的模式。您也可以轻松地将模式模块化;您的类型定义只是字符串,您的解析器只是对象——两者都可以轻松组合。