Gatsby - 使用 createRemoteFileNode 获取远程图像
Posted
技术标签:
【中文标题】Gatsby - 使用 createRemoteFileNode 获取远程图像【英文标题】:Gatsby - fetching remote images with createRemoteFileNode 【发布时间】:2019-03-07 20:26:21 【问题描述】:我一直在尝试从远程 URL 获取图像到 Gatsby 源文件系统,以利用 gatsby-image
插件的延迟加载。我有一个宁静的 API,它返回带有包含图像 url 的字符串的 json。我关注了this guide,因为我对 Gatsby Node Api 还是很陌生,不知道如何解决这个问题。在使用createNodeField
向图像添加附加属性之前,一切都运行良好。似乎添加了属性(当我将 fileNode 记录到控制台时,我可以看到具有 fields
属性的对象。但是,当尝试查询图像时,我收到错误:
我想知道我的代码是否有问题,或者是由于 gatsby 的变化?我正在使用 gatsby 版本2.0.2
。是否有更好的选择以某种方式向图像添加其他属性以便能够仅查询所需的属性?
这是我的gatsby.node.js
的样子:
const axios = require('axios');
const createRemoteFileNode = require(`gatsby-source-filesystem`);
exports.sourceNodes = ( actions, createNodeId, node, store, cache =>
const createNode, createNodeField = actions;
const processProject = project =>
project.photos.forEach(async photo =>
let fileNode;
try
fileNode = await createRemoteFileNode(
url: photo.photo.url,
store,
cache,
createNode,
createNodeId: id => `projectPhoto-$photo.id`,
);
await createNodeField(
node: fileNode,
name: 'ProjectPhoto',
value: 'true',
);
await createNodeField(
node: fileNode,
name: 'created_at',
value: photo.created_at,
);
catch (error)
console.warn('error creating node', error);
);
return axios.get(baseApiUrl).then(res =>
res.data.forEach(project =>
const nodeData = processProject(project);
createNode(nodeData);
);
);
【问题讨论】:
Gatsby 会在您运行 dev/build 命令时获取资产,所以,我会说尝试放松异步模式。它实际上并没有给你任何东西,它可能会混合执行时间,从而导致 Node API 不按顺序触发。 您的意思是只使用.then
来使用 Promise 而不是 async/await?我不认为这应该是一个问题。 gatsby-source-filesystem plugin docs 中的示例也使用了 async/await。
只是一个想法。乱序执行的事情似乎发生了很多与盖茨比建立在我这边。另一件让我很惊讶的事情是,也许您不需要使用节点 API 来执行此操作。我只使用createPage
将最小数据传递到Node 以动态创建页面。在页面本身上,我通过 GraphQL 进行图像查询。这有意义吗?看看我几周前提出的这个问题,与 Contentful 有类似的问题:***.com/questions/52360940/…
谢谢,我没想过只使用createPage
。这实际上很有意义。不幸的是,我还想添加一个包含所有项目列表的索引页面(我不会动态生成该页面,但我想我也可以这样做)。不知何故,我设法通过重组一切来让一切正常工作。我使用了onCreateNode
(除了我创建其他数据的图像)并在那里声明了父/子关系。此外,使用 forEach 似乎与 async/await 配合得不好。我使用了 for of 循环,不知何故这有效。
【参考方案1】:
最后,由于某种原因,使用 .forEach
和 async/await 似乎会搞砸事情。在 for of 循环中做所有事情,解决了问题,尽管 eslint 抱怨了很多。代码如下:
const axios = require('axios');
const createRemoteFileNode = require(`gatsby-source-filesystem`);
exports.sourceNodes = ( actions, createNodeId, node, store, cache =>
const createNode, createNodeField = actions;
const processProject = project =>
for (const photo of project.photos)
let fileNode;
try
fileNode = await createRemoteFileNode(
url: photo.photo.url,
store,
cache,
createNode,
createNodeId: id => `projectPhoto-$photo.id`,
);
await createNodeField(
node: fileNode,
name: 'ProjectPhoto',
value: 'true',
);
await createNodeField(
node: fileNode,
name: 'created_at',
value: photo.created_at,
);
catch (error)
console.warn('error creating node', error);
return axios.get(baseApiUrl).then(res =>
res.data.forEach(project =>
const nodeData = processProject(project);
createNode(nodeData);
);
);
【讨论】:
有趣的解决方案,只是好奇 - 这段代码的最终目标是什么?究竟创建了什么,一大页图片? 我有一个 api,它给我返回 json 和对象数组(每个对象都是一个项目,其中包含一些细节 + 图像的 url)。我想显示给定项目的所有图像以及项目详细信息。最后,我从这里修改了解决方案。我创建了项目节点,然后添加了 ProjectPhoto 节点并在它们之间创建了父/子链接。想法是 1) 从 api 获取数据 2) 使用createRemoteFileNode
从 url 中获取这些图像,因此它们可以延迟加载 3) 在这 2 个节点之间创建连接,以便能够为项目提取正确的图像。跨度>
这是我第一次使用 Gatsby Node API,所以我可能有点过于复杂了,我不能 100% 确定这是否是最好的方法。
你会如何查询这个?
@SakhiMansoor export const pageQuery = graphql
query($id: String!) ProjectImages: project(id: eq: $id ) childrenFile id childImageSharp fluid(maxWidth: 720, quality: 85 ) ...GatsbyImageSharpFluid ;
您可以查看this repo 了解更多上下文。以上是关于Gatsby - 使用 createRemoteFileNode 获取远程图像的主要内容,如果未能解决你的问题,请参考以下文章
在 Gatsby V4 中使用 Gatsby Source Contentful 找不到缓存文件
MDX 中的 Gatsby 静态图像(gatsby-plugin-image)
与gatsby一起使用gatsby-plugin-material-ui时放置主题文件的位置?
尝试使用 `gatsby-source-mongodb` 从 MongoDB 获取数据到 Gatsby