问题
May be the title is not suitable with my problem but let me explain my scenario. I am working with Graphql schema.Here is my initial schema.js file https://github.com/sany2k8/graphql-udemy/blob/master/schema/schema.js
and it was working fine then I decided to split it into different small files e.g root_query_type.js, mutation.js, user_type.js and company_type.js. All the files are exported as module and required circularly. For example -
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;
On my user_type.js file when I use const CompanyType = require('./company_type');
at the top of file like this const UserType it is showing me below error message
Error: User.company field type must be Output Type but got: [object Object].
but if I comment out that line and put it directly then it works.
company :{
type: require('./company_type'),
resolve(parentValue, args){
return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
.then(res => res.data)
}
}
So basically my question is why it is not working with const CompanyType = require('./company_type');
and but working withtype: require('./company_type')
. I could be a simple logical issue but It couldn't able to find.Please help me out.
回答1:
The behavior you're seeing is not specific to GraphQL, but rather node in general. You have cyclic dependencies in your modules, which is causing your require
statement inside user_type.js
to resolve to an incomplete copy of company_type.js
.
According to the docs, given two modules (a.js
and b.js
) that require each other:
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.
Moving the require statements inside your exports definition is one solution. You could also move your exports definition above your require calls to get the same affect. This question looks at cyclic dependencies in more depth and also offers some alternative solutions.
As a side note, this is one of the reasons I would recommend moving away from declaring a GraphQL schema programatically. You can use graphql-tools
's generate-schema to generate a schema from a GraphQL language document. This prevents you from dealings with potential cycle dependencies and results in a much more readable schema. You can modularize your schema easily as well; your type definitions are just strings and your resolvers are just objects -- both of which can easily be combined.
来源:https://stackoverflow.com/questions/45967015/graphql-requiring-module-outside-vs-inside-graphqlobjecttype