问题描述
我正试图从WP中获取一些图像,因为盖茨比目前还不能与woocommerece一起使用.我下面的插件能够转换图像,并在构建时将其添加到.cache,但是它没有在Gatsby graphQl中添加localFile___NODE字段.它似乎根本没有添加任何节点供我使用ImageSharp插件查询.Graphql显示它们是在ALLFiles下处理的,但不在我在Graphql中创建的wcProduct节点中处理的.这是怎么回事,该插件不再创建节点了.
I'm trying to fetch some images from WP because Gatsby doesn't work with woocommerece yet. My plugin below is able to convert the images and add them to .cache when building, but it doesn't add a field of localFile___NODE within the Gatsby graphQl. It doesn't seem to be adding any nodes at all for me to query with ImageSharp plugin. Graphql shows them being processed under ALLFiles but not within the wcProduct node I've created in Graphql...what is going on that this plugin is not creating nodes anymore...
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的数据中添加一个节点.对我来说,我希望将图片网址转换为在盖茨比和ImageSharp插件中使用的图片.这将从我的CMS中获取该图像,并将其转换为"Gatsby图像",可以在wcProduct.images.localFile下的graphQL查询中找到
I realized that I didn't have async loops written properly. This code allows you to pull in data from a remote source, then add a node inside the data that is about to be converted to GraphQL. For me I wanted an image url, to be converted into an image that that I use within Gatsby and the ImageSharp plugin. This takes that image from my CMS, and converts it to a 'Gatsby image' and can be found in graphQL query under wcProduct.images.localFile
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)
}
}
这篇关于获取远程图像并将其转换为gatsby图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!