graphql-code-generator-community icon indicating copy to clipboard operation
graphql-code-generator-community copied to clipboard

`typed-document-node` doesn't create export statement for all document fragments

Open pudek357 opened this issue 2 years ago • 10 comments

Which packages are impacted by your issue?

@graphql-codegen/typed-document-node @graphql-codegen/near-operation-file-preset

Describe the bug

  1. When we create such document file:
import gql from 'graphql-tag';

export const CLIENT_FRAGMENT = gql`
  fragment ClientFragment on Client {
    id
    email
  }
`;

export const USER_FRAGMENT = gql`
  fragment UserFragment on User {
    id
    email
    client {
      ...ClientFragment
    }
  }
  ${CLIENT_FRAGMENT}
`;
  1. then when we generate types, there is an error in *.generated.ts file.

Not all export fragment documents are created in *.generated.ts file.

It's interesting when we introduce such change:

export const USER_FRAGMENT = gql`
  fragment UserFragment on User {
    id
    email
    client {
-      ...ClientFragment
    }
  }
-  ${CLIENT_FRAGMENT}
`;

The export ClientFragmentFragmentDoc is created.

Your Example Website or App

https://stackblitz.com/edit/github-eubitm

Steps to Reproduce the Bug or Issue

  1. Open the URL
  2. run npm run codegen
  3. open test-fragment.document.generated.tsx
  4. you will see that there is an error:

Cannot find name 'ClientFragmentFragmentDoc'. Did you mean 'UserFragmentFragmentDoc'?(2552)

  1. the export document ClientFragmentFragmentDoc was not created

Expected behavior

  1. Open the URL
  2. run npm run codegen
  3. open test-fragment.document.generated.tsx
  4. the export document ClientFragmentFragmentDoc exists

Platform

  • the newest versions of codegen

Codegen Config File

const config: CodegenConfig = {
  schema: 'schema.graphql',
  documents: '**/*.document.ts',
  generates: {
    'types.ts': { plugins: ['typescript'] },
    '/': {
      preset: 'near-operation-file',
      presetConfig: {
        extension: '.generated.tsx',
        baseTypesPath: 'types.ts',
      },
      plugins: ['typescript-operations', 'typed-document-node'],
      config: {
        documentMode: 'graphQLTag',
      },
    },
  },
};

pudek357 avatar Aug 02 '23 14:08 pudek357

Just wanna add that this is the only thing preventing my org from adopting the otherwise excellent TypedDocumentNode. it would be fantastic if this bug got prioritized. The bug does not seem to happen using near-operation-file and regular document nodes or document nodes generated via the react-apollo plugin

dontsave avatar Nov 07 '23 16:11 dontsave

cc @dotansimha ^

dontsave avatar Nov 17 '23 03:11 dontsave

@pudek357 @dontsave what is your reason not to use Codegen's recommended client-preset?

Urigo avatar Nov 19 '23 15:11 Urigo

@Urigo client preset is very cool but far too opinionated for our case. we want typed document nodes to be colocated with the large number of .graphql files we have in our repo. client preset spits out a single file

dontsave avatar Nov 19 '23 15:11 dontsave

can you expand on the reason you need the types to be colocated?

Urigo avatar Nov 19 '23 16:11 Urigo

@Urigo the primary reason is code organization. we have our components organized with their own ./gql/*.gql files. these components import from codegen files generated next to those files. this makes reasoning about the data concerns of each component very straightforward as the gql definitions are right next to the component definitions. it would be a substantial refactor to use the client-preset

a secondary reason is code-splitting. i understand you have an swc plugin, but we have not been able to even get this to work in our limited tests of the preset

dontsave avatar Nov 22 '23 19:11 dontsave

@Urigo just so i'm understanding your line of questioning: should we expect the general momentum of this library to be towards using the client-preset and against using the other plugins (in any combination)?

dontsave avatar Nov 22 '23 19:11 dontsave

@dontsave yes, that is correct. That is why we are having this discussion on the community repo and not the main repo. That doesn't mean we are not doing maintenance work on these plugins, but the main focus is definitely on the client-preset and server-preset. That is also reflected in our official docs

But I do want to understand more your reasoning. You said you have components next to their data dependencies (queries/fragments). We agree with that, that's why we also recommend to use this pattern, as described in this article

About code splitting, are you worried about bundle size? Can you share more details about this when using client-preset?

Urigo avatar Nov 23 '23 16:11 Urigo

@Urigo i see. thanks for the clarification. refactoring our operations to use the client-preset approach feels like it would be a substantial lift in our case, but it's unclear exactly how bad it would be yet. we're willing to give it another shot. it would be nice if there were a guide or tooling for adopting the preset incrementally. i think this has been asked for in other threads as well.

as for code-splitting, i know you have an swc plugin, which is great because we just switched to swc. however we ran into some headwinds in our limited tests of the preset, but i'm gonna take another stab at it before the end of the year. i'll post here with issues

dontsave avatar Nov 27 '23 14:11 dontsave

@Urigo after taking another shot at the client preset, we were not able to get it to work without an enormous lift. here are the challenges we are running into:

  • we prefer to keep our graphql operations in separate .gql files, which we run codegen against. to reference these generated operations with the graphql() function, we have to write the entire operation over again (with \n characters and all). this is duplicative and clumsy and means we can't really use graphql() unless we remove our (hundreds of) .gql files in favor of writing our ops/fragments directly in the graphql template literal function. doing that would lock us into the particulars of graphql-codegen and makes our gql documents less portable and more rigid overall
  • we could not get the swc plugin to work or the babel plugin to work in next 14. this resulted in multiple MB of ops being bundled into a chunk which only referenced a single graphql() op. we used a community alternative to the broken (for next 14) swc plugin, and that worked (eg did not panick), however it failed to code split. similarly with the babel plugin. it would be great to get some more documentation around both

dontsave avatar Dec 07 '23 16:12 dontsave