Relay 编译器

Relay Modern 使用 Relay 编译器将 graphql 代码转换为生成的文件,与源文件一起存在。

当你键入查询时:

graphql`
  fragment MyComponent on Type {
    field
  }
`

这会导致生成的文件出现在 ./__generated__/MyComponent.graphql, 两个运行时工件(有助于从中继存储器读写)和流类型 以帮助您编写类型安全的代码。

Relay 编译器负责生成代码作为构建步骤的一部分,在运行时可以静态使用。通过提前构建查询,客户端的JS运行时不负责生成查询字符串,并且可以在构建步骤中合并查询中重复的字段,以提高解析效率。如果您有能力向服务器持续查询,则编译器的代码生成过程提供了将查询或变式的文本转换为唯一标识符的便利时间,从而大大减少了所需的上传字节数。

设置 Relay 编译器 #

首先,你需要安装 watchman:

brew install watchman

接下来,安装编译器(通常为 devDependency):

yarn add --dev relay-compiler

这将 relay-compiler 在bin_modules文件夹中安装bin脚本。建议通过在 package.json 文件中添加一个脚本来从 yarn/npm 脚本运行:

"scripts": {
  "relay": "relay-compiler --src ./src --schema ./schema.graphql"
}

relay-compiler 脚本需要保存源文件的目录以及.json或.graphql schema文件中的GraphQL schema的路径。

然后在编辑您的应用程序文件后,只需运行 yarn run relay 生成新文件,或者 yarn run relay -- --watch 将编译器作为一个持续的进程运行,每当您保存时自动生成新文件。

可选全局安装 #

或者,您可以 relay-compiler 全局安装,以便您可以直接访问它:

yarn global add relay-compiler

然后在编辑应用程序文件后,运行 relay-compiler --src ./src --schema path/schema.graphql 生成新文件,或者 relay-compiler --src ./src --schema path/schema.graphql --watch 将编译器作为一个持续的进程运行,每当保存时自动生成新文件。

GraphQL Schema #

要使用 Relay 编译器, 您需要一个 .graphql 或 .json GraphQL schema 文件, 描述您的 GraphQL 服务器的API。通常,这些文件是服务器真实来源的本地表示,不会直接编辑。例如,我们可能有一个schema.graphql 如:

schema {
  query: Root
}

type Root {
  dictionary: [Word]
}

type Word {
  id: String!
  definition: WordDefinition
}

type WordDefinition {
  text: String
  image: String
}

源文件 #

此外,您需要一个包含 .js 使用该 graphql 标记的文件的目录来描述GraphQL查询和片段。让我们把这个 ./src

然后 yarn run relay 按照设置运行。

这将创建一系列 __generated__ 与包含 graphql 标签的相应文件位于同一位置的目录。

例如,给定两个文件:

  • src/Components/DictionaryComponent.js

    const DictionaryWordFragment = graphql`
      fragment DictionaryComponent_word on Word {
        id
        definition {
          ...DictionaryComponent_definition
        }
      }
    `
    
    const DictionaryDefinitionFragment = graphql`
      fragment DictionaryComponent_definition on WordDefinition {
        text
        image
      }
    `
  • src/Queries/DictionaryQuery.js

    const DictionaryQuery = graphql`
      query DictionaryQuery {
        dictionary {
          ...DictionaryComponent_word
        }
      }
    `

这将产生三个生成的文件和两个 __generated__ 目录:

  • src/Components/__generated__/DictionaryComponent_word.graphql.js
  • src/Components/__generated__/DictionaryComponent_definition.graphql.js
  • src/Queries/__generated__/DictionaryQuery.graphql.js

导入生成的定义 #

通常,您不需要导入生成的定义。 Relay Babel 插件将转换graphql 代码到 require() 生成的文件。

然而 Relay 编译器也自动生成流类型,作为 类型注释。导入类型:

import type {DictionaryComponent_word} from './__generated__/DictionaryComponent_word.graphql';

高级用法 #

除了bin脚本之外, relay-compiler 软件包还会 导出库代码 您可以使用它来为编译器创建更复杂的配置,或者使用自己的自定义输出来扩展编译器。

如果你发现你需要做一些独特的东西(如生成符合旧版本的流类型,或解析非JavaScript源文件),你可以在内存建立你自己的版本FileWriterASTCache,或通过增加额外的 IRTransform。请注意,内部API RelayCompiler 是不断迭代的,所以滚动更新您自己的版本可能会导致与未来版本的不兼容。