graphql-code-generator
                                
                                
                                
                                    graphql-code-generator copied to clipboard
                            
                            
                            
                        duplicate fragments within queries
Describe the bug
When using fragments in queries which use fragements in multiple positions, the fragments are beeing repeated in the string concatenation, so that most server will complain about it Error: There can be only one fragment named "addressFields".
Your Example Website or App
https://github.com/bastiion/graphql-codegen-duplicate-fragments-issue
Steps to Reproduce the Bug or Issue
- formulate a query that uses same fragments within two other fragments
 - run codegen
 
Expected behavior
fragments must be deduplicated
a work-arround can be ssen here, which would also be an entry point for a bug fix https://github.com/bastiion/graphql-codegen-duplicate-fragments-issue/commit/d08f51ecdd7c3cb6b7af68c7bd24aae5b4a5808a#diff-ca580bb0b9ca66ec74fb97288ee12d571481819ed8e689ea99b2d6ff79dacc24
Screenshots or Videos
No response
Platform
- "@graphql-codegen/cli": "2.3.0",
 - "@graphql-codegen/fragment-matcher": "~3.3.0",
 - "@graphql-codegen/introspection": "~2.2.0",
 - "@graphql-codegen/typescript": "~2.7.1",
 - "@graphql-codegen/typescript-document-nodes": "~2.3.1",
 - "@graphql-codegen/typescript-operations": "~2.5.1",
 - "@graphql-codegen/typescript-react-query": "~3.6.1",
 
Codegen Config File
overwrite: true
schema:
  - http://localhost:9002/graphql
documents: 'graphql/**/*.graphql'
generates:
  graphql/generated/index.ts:
    plugins:
      - 'typescript'
      - 'typescript-operations'
      - 'typescript-react-query'
    config:
      pureMagicComment: true
      fetcher:
        func: ../fetcher#useFetchData
        isReactHook: true
Additional context
example query:
fragment addressFields on Address {
  address
  city
}
fragment personFields on Person {
  name
  address {
    ...addressFields
  }
}
query company {
  company {
    name
    address {
      ...addressFields
    }
    employees {
      ...personFields
    }
  }
}
will produce:
export const AddressFieldsFragmentDoc = /*#__PURE__*/ `
    fragment addressFields on Address {
  address
  city
}
    `;
export const PersonFieldsFragmentDoc = /*#__PURE__*/ `
    fragment personFields on Person {
  name
  address {
    ...addressFields
  }
}
    ${AddressFieldsFragmentDoc}`;
export const CompanyDocument = /*#__PURE__*/ `
    query company {
  company {
    name
    address {
      ...addressFields
    }
    employees {
      ...personFields
    }
  }
}
    ${AddressFieldsFragmentDoc}
${PersonFieldsFragmentDoc}`;
                                    
                                    
                                    
                                
I'm having the same issue, using the URQL codegen
I'm also having the same issue. @bastiion have you found a solution?
I'm also having this issue.
Also having the same issue. Any workarounds would be appreciated!
I was able to work around this using a small wrapper around graphql:
import uniqBy from "lodash/uniqBy";
import type { DocumentNode } from "graphql";
/**
 * Removes duplicate fragments.
 * This is a workaround for this issue: @see https://github.com/dotansimha/graphql-code-generator/issues/8103
 * */
export default function fixFragments<Query extends DocumentNode>(
  query: Query
): Query {
  return { ...query, definitions: uniqBy(query.definitions, "name.value") };
}
(You can use other techniques for deduplicating the fragments by name – I used lodash because we are already using it in our project)
Usage:
await graphQLClient.request(
  fixFragments(
    graphql(/* GraphQL */`
      query YourQuery {
        yourType {
          ...InlineFragment1
          ...InlineFragment2
        }
      }
    `)
  )
)
                                    
                                    
                                    
                                
Hi!
Could you try using the dedupeFragments: true option, as follows:
import { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
  schema: "schema.graphql",
  documents: "document.graphql",
  generates: {
    "types.ts": {
		plugins: [/* your plugin */]
		config: {
			dedupeFragments: true
		}
	},
  },
};
export default config;
                                    
                                    
                                    
                                
For the client preset, the dedupeFragments flag doesn't have an effect. I just upgraded to v1.1.1 of the client preset.
My config:
import type { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
  overwrite: true,
  schema: "http://localhost:3000/graphql",
  documents: "app/**/*.tsx",
  generates: {
    "app/gql/": {
      preset: "client",
      plugins: [],
      config: {
        skipTypename: true,
        dedupeFragments: true,
      },
    },
  },
};
export default config;
                                    
                                    
                                    
                                
    './generated/gql/': {
      // schema: './generated/schema.graphql',
      schema: 'http://localhost:3000/api/graphql',
      documents: ['lib/apollo/modules/**/*.{graphql,tsx,ts}', '!lib/apollo/modules/cms/**/*.{graphql,tsx,ts}'],
      preset: 'client',
      plugins: [],
      presetConfig: {
        fragmentMasking: false,
        dedupeFragments: true
      }
    },
Adding it to presetConfig also does not work
@tojump, I've released your contribution; thanks!
@AssisrMatheus @bernharduw, could you try with @graphql-codegen/[email protected]? 📦
I can confirm it's working for me with v1.1.2!
Good work @tojump + @charlypoly, thanks! 🎉
Should this be on by default? I would expect this to happen very often when combining fragments to form larger queries.
Should this be on by default? I would expect this to happen very often when combining fragments to form larger queries.
@marco2216 I've open an issue to discuss enable options and default with client-preset: https://github.com/dotansimha/graphql-code-generator/issues/8562
@charlypoly i'm getting this issue with client 1.1.3 when i turn on 'typescript' plugin in the array.
- If i disable the typescript plugin, the duplicates seem to dissapear.
 - also none of typescript config are respected with or without typescript plugin in the plugins array.
 
import { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
  schema: 'https://api-sandbox-mumbai.lens.dev/',
  documents: ['src/**/*.tsx'],
  ignoreNoDocuments: true, // for better experience with the watcher
  generates: {
    './src/generated/gql/': {
      preset: 'client',
      plugins: ['typescript-operations', 'typescript-graphql-request', 'typescript-react-query'], //['typescript', 'typescript-operations', 'typescript-graphql-request', 'typescript-react-query'],
      config: {
        enumsAsConst: true,
        // dedupeFragments: true,
        maybeValue: 'T | undefined',
        nonOptionalTypename: true,
        // useTypenameImports: true,
        avoidOptionals: true,
        // fragmentMasking: false,
      },
    },
  },
};
export default config;
                                    
                                    
                                    
                                
Hi @ShravanSunder,
preset: "client" should not be used with any typescript-* plugin, this is what is leading with duplicate types.
Also, client-preset only support a subset of config options, see [client-preset] allowed options and defaults