获取远程图像并将其转换为gatsby图像 [英] Fetching remote images and converting them to gatsby images

查看:66
本文介绍了获取远程图像并将其转换为gatsby图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图从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图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆