问题
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)
})
}
回答1:
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)
}
}
来源:https://stackoverflow.com/questions/55778968/fetching-remote-images-and-converting-them-to-gatsby-images