2

我试图用下面的代码从我在 Gatsby 的 S3 Bucket 中提取远程图像。我有一个构建经典 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.

架构.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,
          });
        },
      },
    },
  });
};
4

1 回答 1

3

好了朋友们,

经过数周的调查。这就是答案,我知道这将帮助许多处理 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 实际上称为 <your_api_name>_s3object。使用此名称,显然您的 api 名称前面已添加....smfh ....将与自定义解析器一起使用,其中包含 gql 查询,以将文件添加到您的模型中。见下文。现在,无论您在哪里添加 S3Object 作为字段类型,您都可以通过图像清晰查询访问图像! 您还必须使用 gatsby-s3-image-source 来抓取所有要用于文件系统的图像!

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

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);
};
于 2020-07-12T17:00:08.977 回答