Fetching remote images and converting them to gatsby images

≡放荡痞女 提交于 2021-02-11 14:14:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!