【问题标题】:Fetching remote images and converting them to gatsby images获取远程图像并将其转换为 gatsby 图像
【发布时间】:2019-09-10 17:39:05
【问题描述】:

我正在尝试从 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)
  })
}

【问题讨论】:

    标签: reactjs graphql gatsby


    【解决方案1】:

    我意识到我没有正确编写异步循环。此代码允许您从远程源中提取数据,然后在即将转换为 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)
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-03-07
      • 2013-03-28
      • 2017-07-27
      • 2016-07-07
      • 2020-09-02
      • 1970-01-01
      • 1970-01-01
      • 2018-11-24
      • 1970-01-01
      相关资源
      最近更新 更多