GatsbyJS документы дает этот пример для доступа к файлу по относительному пути с GraphQL:
export const query = graphql`
query {
fileName: file(relativePath: { eq: "images/myimage.jpg" }) {
childImageSharp {
fluid(maxWidth: 400, maxHeight: 250) {
...GatsbyImageSharpFluid
}
}
}
}
`
Я просто не могу заставить это работать, и я не знаю, почему. Я пробовал всевозможные синтаксисы, но запрос всегда возвращает null для имени файла. Это моя последняя попытка в GraphяQL:
{
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? Как это однозначно определяет путь?


Поле relativePath узла File относится к каталогу, который вы указали в 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
}
}
Потому что он вернет первый узел файла, который удовлетворяет условию фильтра (я не уверен, как Гэтсби определяет порядок файлов, если кто-то знает, поделитесь!). Будет безопаснее добавить несколько дополнительных уникальных фильтров.
Например, когда я устанавливаю 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
}
}
Я думаю, что комбинации sourceInstanceName и relativePath достаточно, чтобы файл был уникальным.
Кроме того, вы также можете запросить узел File по его absolutePath. Это гарантирует, что файл уникален, хотя вам все равно нужно сообщить gatsby-source-filesystem, где находится файл.
Если вы хотите увидеть все файлы с одинаковым relativePath, этот запрос будет выполняться:
query {
allFile(filter: {
relativePath: { eq: "index.md" }
}) {
edges {
node {
id
}
}
}
}
@AtteJuvonen Привет, Атте! Я обновил ответ, чтобы ответить на отредактированный вопрос. Короче говоря, если вы полагаетесь только на relativePath, Gatsby не будет знать, какой файл вам нужен, и просто вернет первый найденный файл. Вам придется добавить дополнительные фильтры, чтобы убедиться, что файл уникален.
Кроме того, вы также можете запросить узел File по его полю absolutePath, и в этом случае вам не нужно будет передавать дополнительные фильтры.
Это действительно хороший ответ, требующий комментария, а не просто голосования. :-) Кажется, это не ясно указано в Страница плагина Gatsby gatsby-source-filesystem или его репозиторий GitHub. Спасибо.
Отличный ответ!
Что меня зацепило, так это то, что для Эта проблема вам нужно перезапустить gatsby develop для обновления данных GraphQL (т.е. после того, как вы настроите relativePath).
Это можно решить:
ENABLE_GATSBY_REFRESH_ENDPOINT=true gatsby developcurl -X POST localhost:8000/__refresh в отдельном терминале каждый раз, когда вы хотите обновить данные
Большое спасибо, еще раз! Это работает, хотя мне все еще интересно, как это однозначно определяет путь? Я отредактировал ОП, чтобы уточнить, что я имею в виду под этим вопросом.