reactjs - 获取远程图像并将其转换为 gatsby 图像
问题描述
我正在尝试从 WP 获取一些图像,因为 Gatsby 还不能与 woocommerece 一起使用。我下面的插件能够在构建时转换图像并将它们添加到 .cache 中,但它不会在 Gatsby graphQl 中添加 localFile___NODE 字段。我似乎根本没有添加任何节点来使用 ImageSharp 插件进行查询。Graphql 显示它们正在 ALLFiles 下处理,但不在我在 Graphql 中创建的 wcProduct 节点内处理……这个插件不再创建节点是怎么回事……
const utils = require("./utils")
const fetch = require("node-fetch")
const queryString = require("query-string")
const fs = require("fs-extra")
const { createRemoteFileNode } = require(`gatsby-source-filesystem`)
exports.sourceNodes = async (
{
actions, createNodeId, createContentDigest, store, cache
},
configOptions
) => {
const { createNode } = actions
await fs.removeSync("/.cache")
// Gatsby adds a configOption that's not needed for this plugin, delete it
delete configOptions.plugins
// Helper function that processes a product to match Gatsby's node structure
const processProduct = async (product, args) => {
// console.log("product", product)
// https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-filesystem#createremotefilenode
// download and add image to local file
await product.images.map(async image => {
const fileNode = await createRemoteFileNode({
...args,
url: image.fullSize.url
})
image.localFile___NODE = fileNode.id
})
const nodeId = createNodeId(`wc-product-${product.id}`)
const nodeContent = JSON.stringify(product)
// Node info
return Object.assign({}, product, {
id: nodeId,
parent: null,
children: [],
internal: {
type: `wcProduct`,
content: nodeContent,
contentDigest: createContentDigest(product)
}
})
}
const apiUrl = `${process.env.GATSBY_DB}/wp-json/et-shop/graphql/products`
const apiResponse = await fetch(apiUrl)
const results = await apiResponse.json()
const jsonResults = JSON.stringify(utils.transformNormalizedData(results.data))
fs.writeFileSync("src/state/products.json", jsonResults)
results.data.forEach(async (product) => {
// Process the product data to match the structure of a Gatsby node
const productNode = await processProduct(product, { store, cache, createNode, createNodeId })
// Use Gatsby's createNode helper to create a node from the node data
createNode(productNode)
})
}
解决方案
我意识到我没有正确编写异步循环。此代码允许您从远程源中提取数据,然后在即将转换为 GraphQL 的数据中添加一个节点。对我来说,我想要一个图像 url,将其转换为我在 Gatsby 和 ImageSharp 插件中使用的图像。这会从我的 CMS 中获取该图像,并将其转换为“Gatsby 图像”,并且可以在 wcProduct.images.localFile 下的 graphQL 查询中找到
const utils = require("./utils")
const fetch = require("node-fetch")
const fs = require("fs-extra")
const { createRemoteFileNode } = require(`gatsby-source-filesystem`)
exports.sourceNodes = async (
{
actions, createNodeId, createContentDigest, store, cache
},
configOptions
) => {
const { createNode } = actions
await fs.removeSync("/.cache")
// Gatsby adds a configOption that's not needed for this plugin, delete it
delete configOptions.plugins
// Helper function that processes a product to match Gatsby's node structure
const processProduct = async (product, args) => {
// https://flaviocopes.com/javascript-async-await-array-map/
product.images = await Promise.all(product.images.map(async image => {
let fileNode
try {
fileNode = await createRemoteFileNode({
url: image.fullSize.url,
...args
})
} catch (e) {
console.log("e", e)
}
if (fileNode) {
console.log("createdFile node")
image.localFile___NODE = fileNode.id
return image
}
}))
const nodeId = createNodeId(`wc-product-${product.id}`)
const nodeContent = JSON.stringify(product)
// Node info
return Object.assign({}, product, {
id: nodeId,
parent: null,
children: [],
internal: {
type: `wcProduct`,
content: nodeContent,
contentDigest: createContentDigest(product)
}
})
}
const apiUrl = `${process.env.GATSBY_DB}/wp-json/et-shop/graphql/products`
const apiResponse = await fetch(apiUrl)
const results = await apiResponse.json()
const jsonResults = JSON.stringify(utils.transformNormalizedData(results.data))
fs.writeFileSync("src/state/products.json", jsonResults)
await asyncForEach(results.data, async (product) => {
const productNode = await processProduct(product, { store, cache, createNode, createNodeId })
createNode(productNode)
})
}
// https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
async function asyncForEach (array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
}
推荐阅读
- javascript - 如何使用正则表达式提取没有路径参数或查询参数的 url 的相对路径?
- visual-studio-code - VSCode 在 OS 更新后以黑底灰显示代码
- pyspark - 如何将字符串附加到pyspark中列出的数据框列
- python - 无法加载请求的 DLL 找不到指定的模块
- assembly - 反向字符串 MASM
- c++ - 如何在 C++ 中将空格分隔的输入插入数组
- linux - 如果我将浮点数除以零,为什么会引发“浮点异常”?
- python - 如何在matplotlib中向相反方向(向下)添加第三个y轴?
- python - 语音字符到语音
- file - URLDownloadToFile 中的 IBindStatusCallback 未正确返回最终文件大小