You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gatsby调用touchNode处理页面节点时报TypeError: pageResources未定义

解决touchNode后访问缓存页面出现TypeError: locationAndPageResources.pageResources is undefined的问题

这个错误的核心原因是:你只touchNode了页面节点本身,但Gatsby缓存中与该页面关联的PageResources节点已经被垃圾回收机制清理了——Gatsby的页面渲染依赖页面节点和对应的PageResources(包含组件、数据等资源),两者缺一不可。

下面是具体的解决方案,按优先级排序:

1. 同时Touch页面节点和对应的PageResources节点

Gatsby中每个页面节点都会关联一个PageResources节点,你需要找到这个关联节点并一起touch,确保它不会被清理。修改你的代码如下:

await Promise.all(result.data.pages.map(async page => {
  const pageCacheKey = `cache-${page.url}`
  const cacheResult = await pageRecords.getKey(pageCacheKey)
  if (cacheResult) {
    const node = pageNodes.find(node => {
      if (!node.context) return
      return node.context.url == page.url
    })
    if (node) {
      if (node.context.lastPublishedAt == page.lastPublishedAt) {
        pageRecords.setKey(pageCacheKey, localPublishedAt)
        
        // 找到对应的PageResources节点
        const pageResources = getNodesByType(`PageResources`).find(pr => 
          pr.page?.node?.id === node.id
        );
        
        // 先touch页面节点,再touch资源节点
        await touchNode({ nodeId: node.id });
        if (pageResources) {
          await touchNode({ nodeId: pageResources.id });
        }
      }
    }
  }
}))

注意:getNodesByType是Gatsby API提供的方法,需要确保你的代码在支持该方法的API上下文(比如sourceNodes、onCreatePage)中运行。

2. 验证缓存键与资源关联的一致性

有时候缓存键的命名或匹配逻辑可能导致页面与资源的关联断裂,建议:

  • 检查pageCacheKey的生成逻辑是否唯一对应每个页面
  • 确认node.context.url与page.url的匹配逻辑没有大小写或路径格式的问题(比如末尾是否带斜杠)

3. 手动缓存PageResources作为兜底

如果上述方法仍有问题,可以通过Gatsby的缓存API手动保存PageResources的内容,确保它不会被清理:

if (node.context.lastPublishedAt == page.lastPublishedAt) {
  const pageResources = getNodesByType(`PageResources`).find(pr => 
    pr.page?.node?.id === node.id
  );
  
  // 缓存PageResources内容
  if (pageResources) {
    await pageRecords.setKey(`${pageCacheKey}-resources`, JSON.stringify(pageResources));
  }
  
  pageRecords.setKey(pageCacheKey, localPublishedAt);
  await touchNode({ nodeId: node.id });
  if (pageResources) {
    await touchNode({ nodeId: pageResources.id });
  }
}

这样即使缓存意外清理,也可以从手动缓存中恢复PageResources(不过通常不需要这一步,除非你的缓存策略有特殊需求)。

内容的提问来源于stack exchange,提问作者Nathan Horrigan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:51:33