模式中不存在的 Gatsby `S3Object`。在添加解析器之前使用 `createTypes` 添加类型

Gatsby `S3Object` that doesn't exist in the schema. Use `createTypes` to add the type before adding resolvers

我正在尝试使用以下代码从我在 Gatsby 中的 S3 存储桶中提取远程图像。我有一个构建经典 S3Object 的 schema.graphql。但是 Gatsby Node 会抛出以下错误。在这个问题上,我已经在文档中待了好几天,有人能指出我正确的方向吗?我只需要将图像放入 Gatsby 的数据层,这样我就可以使用 Gatsby-image 了。

我觉得我需要更新 S3Object 以扩展节点接口,我正在处理这个问题。

错误:

warn `createResolvers` passed resolvers for type `S3Object` that doesn't exist in the schema. Use `createTypes` to add the type before adding resolvers.

schema.graphql

type PortfolioItem @model @key(fields: ["title", "createdAt"]) {
  id: ID!
  title: String!
  file: S3Object
  thumbnailUrl: String
  ...
}

type S3Object {
  bucket: String!
  key: String!
  region: String!
}

盖茨比-node.js

exports.createResolvers = ({ actions, cache, createNodeId, createResolvers, store, reporter }) => {
  const { createNode } = actions;
  createResolvers({
    S3Object: {
      imageFile: {
        type: `File`,
        resolve(source, args, context, info) {
          return createRemoteFileNode({
            url: 'https://my-aws-bucket-url.s3.us-east-2.amazonaws.com/' + source.key,
            store,
            cache,
            createNode,
            createNodeId,
            reporter,
          });
        },
      },
    },
  });
};

好的,

经过数周的调查。这就是答案,我知道这会帮助很多人处理 Gatsby 和远程图像。

这里的全部目标是直接访问 graphql 模型中字段上的远程图像。不要循环遍历来自某些 Gatsby listAllImages 查询的长图像数组和类似的废话。这会将一个实际的 USEABLE GATSBY-IMAGE 直接添加到模型的一个字段中,以便立即使用。

  1. 在您的 Schema.Graphql 中定义一个 S3Object,如下所示。
type S3Object {
  bucket: String!
  key: String!
  region: String!
}
  1. 这里的答案是在您的 gatsby 节点文件中创建自定义解析器。这里的技巧是进入 gatsby 级别模式并查看模型的真实名称。这就是秘密。您需要 运行:
gatsby repl

这会让您进入 Gatsby 的 CLI,然后输入:

schema

这将向您显示已编译的架构级别名称。所以你的S3Object实际上叫做_s3object。使用此名称,显然前面有您的 api 名称....smfh....将与自定义解析器一起使用,其中包含一个 gql 查询,以将文件添加到您的模型中。见下文。现在,无论您将 S3Object 添加为字段类型,您都可以通过图像清晰查询访问图像! 你还必须使用 gatsby-s3-image-source 来抓取所有要使用的图像到你的文件系统中!

对于像我这样的菜鸟来说,这是一个超级复杂的 Gatsby 解决方案,我希望这能解决像我这样的其他人的远程文件问题!

exports.createResolvers = ({ createResolvers }) => {
  const resolvers = {
    ryanthedev_S3Object: {
      imageFile: {
        type: 'File', // this needs to be 'File', since it's not returning an 'ImageSharp' node anymore
        resolve: (source, args, context, info) => {
          // A promise is expected to be returned anyway so don't need
          // to `await` the result here, if all we're doing is returning
          // the `File` node
          return context.nodeModel.runQuery({
            query: {
              filter: {
                base: { eq: source.key },
              },
            },
            type: 'File',
            firstOnly: true,
          });
        },
      },
    },
  };
  createResolvers(resolvers);
};