Gatsby V3升级至V4后getNodesByType无法获取数据如何解决
问题根因
Gatsby V4 调整了节点生命周期的执行逻辑,onCreateNode 会在单个节点创建后立即触发,不会等待所有源节点加载完成。你在处理StrapiRealisations节点时调用getNodesByType('StrapiSecteurs'),此时对应的Strapi类目节点大概率还未被源插件拉取创建完成,因此返回空数组。
解决方案
方案1(推荐,符合V4设计规范):通过自定义GraphQL解析器实现关联
不需要在创建节点时提前注入关联数据,在GraphQL查询阶段自动完成关联,彻底规避节点创建顺序问题:
const getCitation = require('./你的getCitation方法路径') // 自行替换实际路径 exports.createResolvers = ({ createResolvers }) => { createResolvers({ // 给自定义的MDRealisation类型添加关联解析逻辑 MDRealisation: { client: { secteur: { type: "StrapiSecteurs", resolve: async (source, _, { nodeModel }) => { if (!source.client?.secteur) return null // 通过节点模型查询对应id的类目节点 return nodeModel.getNodeById({ id: source.client.secteur, type: "StrapiSecteurs" }) } } }, // 同理处理citation字段 citation: { resolve: (source) => getCitation(source) } } }) }
调整后原来的onCreateNode逻辑可以简化,不需要调用getSecteur,直接保留原始的secteur id即可。
方案2:调整自定义节点创建时机
如果一定要在节点创建阶段就写入关联数据,可以等到所有源节点全部加载完成后,统一创建自定义节点:
const { createContentDigest } = require("gatsby-core-utils") const getCitation = require('./你的getCitation方法路径') // 临时存储所有需要处理的StrapiRealisations节点 const realisationNodes = [] exports.onCreateNode = ({ node }) => { if (node.internal.type === "StrapiRealisations") { realisationNodes.push(node) } } // 所有源节点创建完成后触发该API exports.onPostSourceNodes = async ({ actions, getNodesByType }) => { const { createNode } = actions // 此时可以拿到全量的StrapiSecteurs节点 const secteurs = getNodesByType(`StrapiSecteurs`) realisationNodes.forEach(node => { let matchedSecteur = null if (node.client?.secteur) { matchedSecteur = secteurs.find( (secteur) => secteur.strapiId === node.client.secteur ) } createNode({ ...node, id: `${node.id}-markdown`, parent: node.id, children: [], client: { ...node.client, secteur: matchedSecteur, }, citation: getCitation(node), internal: { type: "MDRealisation", contentDigest: createContentDigest(node), }, }) }) }
注意Gatsby V4 已废弃全局的digest方法,需要使用官方提供的createContentDigest生成内容哈希。
内容的提问来源于stack exchange,提问作者Crakenar
相关产品推荐
相关产品推荐

