Graphql-tag: External fragments are not pulled into the query document using the loader.

Created on 23 Feb 2017  路  9Comments  路  Source: apollographql/graphql-tag

The fragments are not pulled into the query document using the loader.

Example:

# ContactFragment.gql
fragment Contact on ContactType {
    phone
    email
}
# UserInfo.gql
fragment UserInfo on UserInfoType {
    id
    name
    contact {
        address
        ...Contact
    }
}
# User.gql
query User($email: String) {
  user(email: $email) {
    ...UserInfo
  }
}
# Users.gql
query Users($emails: [String]) {
  users(emails: $emails) {
    ...UserInfo
  }
}
// Both of the following Nodes fail when used with apollo client.
The error is: `Unknown fragment \"UserInfo\".`

const UserQueryNode: DocumentNode = require('graphql-tag/loader!../../graphql/User.gql');
const UsersQueryNode: DocumentNode = require('graphql-tag/loader!../../graphql/Users.gql');

The apollo-codegen handles the above scenario well when generating the schema.ts file.
However, graphql-tag/loader is unable to insert the fragments in this example.

One thing to notice is that graphql-tag/loader works well when the fragments are also located in the same file as the query that is referencing them.

The fragments should be pulled in via the loader, however, that is not the case as per this issue.

So, we need the fragments to be in separate files and apollo-codegen handles them properly when compiling the schema.ts. We just have to ensure that the loader in this module is also properly including them in each query.

=====
Version:
"graphql-tag": "^1.2.4",
node: 6.9.5
os: darwin x64

bug easy

Most helpful comment

You can use the new import syntax, as in:

#import "./UserInfo.gql"
query Users($emails: [String]) {
...

Does that help?

All 9 comments

You can use the new import syntax, as in:

#import "./UserInfo.gql"
query Users($emails: [String]) {
...

Does that help?

@czert -- Not working - This is run under Angular CLI & Webpack. With no access to modify Webpack's config to add the loader, Webpack errors saying it doesn't know how to load the (fragment) file.

Only if the loader could invoke itself to load the fragments recursively, all would work fine.

I believe that this line may be the culprit.

@un33k setting up webpack so that it uses graphql-tag/loader for all *.gql imports should help, i think.

@czert as I mentioned above, Webpack config is handled by Angular CLI. So at this time, there is no way to pass the loader option to Webpack.

I think it might be related to this
https://github.com/apollographql/graphql-tag/issues/76

also related to #64 and failing test PR submitted here: #65

@un33k without using the #import syntax, there's no way for us to be able to pull in the required fragment definition - with the webpack loader, each document is treated (and compiled) separately, with no knowledge of previous iterations.

in particular, we have trouble with the case where the webpack loader compiles a graphql document which includes a fragment that we have not yet discovered; there's no way for us to "wait" until the entire tree of modules has been crawled to then fulfill the fragment definition. i had _some_ thoughts around having a webpack plugin that could handle resolving across the entire project, but it would lead to duplicate fragments (and in general felt like a lot of work).

the newest version of [email protected] has a few fixes for the webpack loader, so its possible that that may resolve this as well. going to close this with the recommendation to use the #import syntax (which just falls back to the normal "require" resolution)

@jnwng if the loader does batch processing, then there is no need for any inclusion tags. On the first pass, it loads all files and caches all fragments & actions. Then it loops through the actions and populates the fragments. In the case of duplicates, a flag can be set to let the last win or raise an error. This is done at the start of your app, and only once.

Same issue here. I was able to add the graphql-tag/loader to Angular CLI's webpack build without ejecting using ngx-build-plus.

webpack.partial.js:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(graphql|gql)$/,
        exclude: /node_modules/,
        loader: 'graphql-tag/loader',
      },
    ],
  },
};
Was this page helpful?
0 / 5 - 0 ratings