带内插的graphql-codegen动态字段

我正在使用graphql-codegen从graphql模式生成打字稿类型。我正在尝试使用动态字段创建一个片段。

schema.ts

这是graphql-codegen生成的类型。

/** User Type */
export type UserType = {
  __typename?: 'UserType';
  id: Scalars['ID'];
  avatar: Scalars['String'];
  email: Scalars['String'];
  name: Scalars['String'];
  showPostsInFeed: Scalars['Boolean'];
  username: Scalars['String'];
};

user.model.ts

我在整个应用程序中都使用这些接口来进行验证和一致性。

export interface IUserBase {
  id: string;
  avatar: string;
  name: string;
  username: string;
}

export interface IUserPost extends IUserBase {
  showPostsInFeed: boolean;
}

export interface IUserProfile extends IUserBase,IUserPost {
  email: string;
}

show.ts

这是用于生成的文件。在这里,我想使用现有的IUserPostIUserProfile接口创建一个带有动态字段的片段,以便重用这些字段,并避免重复在片段中一一重复它们。

import gql from 'graphql-tag';
import { keys } from 'ts-transformer-keys';

import { IUserProfile,IUserPost } from '../../user.model';

const keysUserPofile = keys<IUserProfile>();  //Get all interface keys
const keysUserPost = keys<IUserPost>();  //Get all interface keys

//Fragments
export const fragments = {
  userProfile: gql`
    fragment UserProfile on UserType {
      ${keysUserPofile.join('\n')}    //Interpolation
    }
  `,userPost: gql`
    fragment UserPost on UserType {
      ${keysUserPost.join('\n')}    //Interpolation
    }
  `
};

//Queries
export const userProfileQuery = gql`
    query UserProfileQuey($id: String!) {
      showUser(id: $id) {
        ...UserProfile
      }
    }
`;

export const userPostQuery = gql`
    query UserPostQuey($id: String!) {
      showUser(id: $id) {
        ...UserPost
      }
    }
`;

当我尝试使用插值传递这些字段时,出现此错误。

$ npm run generate

> gogofans-ui@0.0.0 generate C:\Development\GogoFans\gogofans-ui
> graphql-codegen --config codegen.yml

  √ Parse configuration
  > Generate outputs
    > Generate src/app/core/graphql/schema.ts
      √ Load GraphQL schemas
      × Load GraphQL documents
        → Syntax Error: Expected Name,found "}".
        Generate


 Found 1 error

  × C:/Development/GogoFans/gogofans-ui/src/app/users/graphql/fragments/show.ts
    GraphQLError: Syntax Error: Expected Name,found "}".
        at syntaxError (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\error\syntaxError.js:15:10)
        at Parser.expectToken (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1423:40)     
        at Parser.parseName (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:92:22)
        at Parser.parseField (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:289:28)       
        at Parser.parseSelection (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:278:81)   
        at Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
        at Parser.parseSelectionSet (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:265:24)
        at Parser.parseFragmentDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:410:26)
        at Parser.parseDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:134:23)     
        at Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
        at Parser.parseDocument (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:109:25)       
        at Object.parse (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:36:17)
        at Object.parseGraphQLSDL (C:\Development\GogoFans\gogofans-ui\node_modules\@graphql-tools\utils\index.cjs.js:601:28)
        at parseSDL (C:\Development\GogoFans\gogofans-ui\node_modules\@graphql-tools\code-file-loader\index.cjs.js:239:18) 
        at CodeFileLoader.load (C:\Development\GogoFans\gogofans-ui\node_modules\@graphql-tools\code-file-loader\index.cjs.js:173:28)
        at async loadFile (C:\Development\GogoFans\gogofans-ui\node_modules\@graphql-tools\load\index.cjs.js:48:24)        
    GraphQLError: Syntax Error: Expected Name,found "}".
        at syntaxError (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\error\syntaxError.js:15:10)
        at Parser.expectToken (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1423:40)        
        at Parser.parseName (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:92:22)
        at Parser.parseField (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:289:28)
        at Parser.parseSelection (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:278:81)      
        at Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
        at Parser.parseSelectionSet (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:265:24)   
        at Parser.parseFragmentDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:410:26)
        at Parser.parseDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:134:23)     
        at Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
        at Parser.parseDocument (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:109:25)       
        at Object.parse (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:36:17)
        at Object.parseGraphQLSDL (C:\Development\GogoFans\gogofans-ui\node_modules\@graphql-tools\utils\index.cjs.js:601:28)
        at parseSDL (C:\Development\GogoFans\gogofans-ui\node_modules\@graphql-tools\code-file-loader\index.cjs.js:239:18) 
        at CodeFileLoader.load (C:\Development\GogoFans\gogofans-ui\node_modules\@graphql-tools\code-file-loader\index.cjs.js:173:28)
        at async loadFile (C:\Development\GogoFans\gogofans-ui\node_modules\@graphql-tools\load\index.cjs.js:48:24)        


Something went wrong
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! gogofans-ui@0.0.0 generate: `graphql-codegen --config codegen.yml`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the gogofans-ui@0.0.0 generate script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Fidel\AppData\Roaming\npm-cache\_logs\2020-07-06T07_01_25_424Z-debug.log

iCMS 回答:带内插的graphql-codegen动态字段

GraphQL代码生成器正在使用代码AST查找操作(使用graphql-tag-pluck)。它不执行字符串插值,因为在某些情况下,它是仅在应用程序运行时确定的,或者它可能是代码生成器无法真正访问的内部变量。

为了运行字符串插值-我们需要编译并运行您的代码文件,而代码生成器实际上无法做到这一点。

为什么需要进行字符串插值?您能解释一下您的用例吗?因为如果是用于分隔字段列表,请使用GraphQL片段。如果是为了动态更改字段集,请使用内置的@skip@include指令。 如果您仍然需要更多控制代码生成器加载文档的方式,请使用自定义文档加载器:https://graphql-code-generator.com/docs/getting-started/documents-field#custom-document-loader

我认为,使用.graphql文件进行GraphQL操作更简单,并让代码生成器使用typescripttypescript-operations和{{1}生成现成的代码}插件-通过这种方式,您将根据您的操作获取Angular typescript-apollo-angular,并且完全是类型安全的,并且GraphQL操作已在内部定义。

,

由于架构是静态的,因此字段不会更改。就是说,您可以将所有可能的字段添加到选择集中,然后再使用@skip@include指令对其进行过滤。

GraphQL Codegen及其使用的工具不支持字符串插值,也不会增加对它的支持,因为为了获得最终的字符串,我们需要加载,编译和查找该导出的标识符。这样做将使代码生成的设置更加复杂-由于JS生态系统中的多种功能。

GraphQL模式和操作可以定义为静态字符串,并且您应该能够使用指令或类似操作动态地控制选择集。

下面是在片段传播中使用内置@skip@include指令的示例:

query UserProfileQuery($id: String!,$loadA: Boolean,$loadB: Boolean) {
      showUser(id: $id) {
        ...UserFieldsA @include(if: $loadA)
        ...UserFieldsB @include(if: $loadB)
      }
    }

fragment UserFieldsA {
  id
  a
}

fragment UserFieldsB {
  id
  b
}

通过这种方式,您可以在运行时通过从JS代码中设置变量$loadA$loadB来动态地控制它。

这些指令的定义类似于GraphQL:

directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

这意味着您可以在字段,片段传播或内联片段上使用它-因此它应该为您提供足够的灵活性来管理复杂和动态的选择集。

本文链接:https://www.f2er.com/1993664.html

大家都在问