【问题标题】:GraphQL syntax to access file by relativepath通过相对路径访问文件的 GraphQL 语法
【发布时间】:2019-06-30 06:54:04
【问题描述】:

GatsbyJS docs 给出这个例子,使用 GraphQL 通过相对路径访问文件:

export const query = graphql`
  query {
    fileName: file(relativePath: { eq: "images/myimage.jpg" }) {
      childImageSharp {
        fluid(maxWidth: 400, maxHeight: 250) {
          ...GatsbyImageSharpFluid
        }
      }
    }
  }
`

我就是不能让这个工作,我不知道为什么。我尝试了各种不同的语法,但查询总是为文件名返回 null。这是我最近在 GraphiQL 中的尝试:

{
    fileName: file(relativePath: { eq: "./html.js" }) {
      id
    } 
}

我错过了什么?如何通过相对路径访问文件?

阅读答案后编辑:

在我的gatsby-config.js 中有几个路径设置为可查询:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `images`,
    path: `${__dirname}/src/images/`
  }
},
{
  resolve: `gatsby-source-filesystem`,
  options: {
    path: `${__dirname}/content/posts/`,
    name: "posts"
  }
},
....

当我查询pic.jpg(而不是images/pic.jpg)时,盖茨比怎么知道我想要images/pic.jpg而不是posts/pic.jpg?这是如何唯一定义路径的?

【问题讨论】:

    标签: graphql gatsby


    【解决方案1】:

    File 节点的relativePath 字段相对于您在gatsby-source-filesystem 中指定的目录。

    例如,假设我有一个这样的目录结构:

    root
      |--gatsby-config.js
      `--dirA
          |--fileA.md
          `--dirB
              |--fileB.md
              `--dirC
                   `--fileC.md
    

    在我的gatsby-config.js

    {
      resolve: `gatsby-source-filesystem`
      options: {
        path: `${__dirname}/dirA`, <---- root/dirA
        name: `dir`,
      },
    }
    

    dirA 内的文件将具有以下relativePath

    File      |  relativePath
    ---------------------------------
    fileA.md  |  'fileA.md'
    ---------------------------------
    fileB.md  |  'dirB/fileB.md'
    ---------------------------------
    fileC.md  |  'dirB/dirC/fileC.md'
    

    我可以这样查询fileC

    query {
      fileName: file(relativePath: {
        eq: "dirB/dirC/fileC.md"
      }) {
        id
      }
    }
    

    所以在你的情况下,你可以将gatsby-source-filesystem指向html.js的父目录,它应该是可查询的。


    获取唯一文件

    如果我有以下结构:

    root
      |--gatsby-config.js
      |--dirD
      |   `--index.md
      `--dirE
          `--index.md
    

    并将gatsby-source-filesystem 指向它们两个,现在有2 个文件节点具有相同的relativePath (index.md)。

    在这种情况下,执行以下查询是不安全的:

    query {
      fileName: file(relativePath: {
        eq: "index.md"
      }) {
        id
      }
    }
    

    因为它会返回第一个满足过滤条件的 File 节点(我不确定 gatsby 是如何决定文件顺序的,如果有人知道请分享!)。添加一些额外的独特过滤器会更安全。

    例如,当我设置gatsby-source-filesystem 时,我可以指定name 属性。这个name 将存储在文件节点上的sourceInstanceName 字段中。

    {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/dirE`,
        name: `dirE`,
      },
    },
    

    我可以这样查询:

    {
      file(
        relativePath: {
          eq: "index.md"
        },
        sourceInstanceName: {
          eq: "dirE"
        }
      ) {
        id
      }
    }
    

    我认为sourceInstanceNamerelativePath 的组合足以确保文件的唯一性。

    或者,您也可以通过其absolutePath 查询文件节点。这将保证文件是唯一的,但您仍然需要告诉 gatsby-source-filesystem 文件所在的位置。

    如果您想查看具有相同 relativePath 的所有文件,则此查询将执行:

    query {
      allFile(filter: {
        relativePath: { eq: "index.md" }
      }) {
        edges {
          node { 
            id
          }
        } 
      }
    }
    

    【讨论】:

    • 再次感谢您!这可行,但我仍然想知道这是如何独特地定义路径?我编辑了 OP 以澄清这个问题的含义。
    • @AtteJuvonen 嗨,阿特!我已经更新了答案以解决已编辑的问题。简而言之,如果你只依赖relativePath,Gatsby 将不知道你想要哪个文件,只会返回它可以找到的第一个文件。您必须添加额外的过滤器以确保文件是唯一的。
    • 另外,您也可以通过其absolutePath 字段查询文件节点,在这种情况下您不需要传递额外的过滤器。
    • 这是一个非常好的答案,需要评论,而不仅仅是投票。 :-) 这似乎没有在Gatsby gatsby-source-filesystem plugin pageits GItHub repo 上明确说明。谢谢。
    • 很好的答案!
    【解决方案2】:

    让我感到惊讶的是,对于 this issue,您需要重新启动 gatsby develop 才能刷新 GraphQL 数据(即在您调整 relativePath 之后)。

    这可以通过以下方式解决:

    • ENABLE_GATSBY_REFRESH_ENDPOINT=true gatsby develop 启动 Gatsby
    • 每次要刷新数据时,在单独的终端中运行 curl -X POST localhost:8000/__refresh

    【讨论】:

      猜你喜欢
      • 2020-01-28
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      • 1970-01-01
      • 2012-02-27
      相关资源
      最近更新 更多