如何在运行Gatsby构建/开发时修复不变违规错误

3
我正在使用 node v16.0.0Gatsby v3.6.1Yarn v1.22.10作为依赖管理器,并使用以下插件:

我在文件gatsby-node.js中使用了以下函数来创建可以在以后查询的带有图像的GraphQL节点:

// gatsby-node.js
const { createRemoteFileNode } = module.require(`gatsby-source-filesystem`)

exports.onCreateNode = async ({   node,
  actions: { createNode },
  store,
  cache,
  createNodeId,
 }) => {
  if (node.internal.type === `API__images` && node.pk) {
    let fileNode = await createRemoteFileNode({
      url: node.url, // string that points to the URL of the image
      parentNodeId: node.id, // id of the parent node of the fileNode you are going to create
      createNode, // helper function in gatsby-node to generate the node
      createNodeId, // helper function in gatsby-node to generate the node
      cache, // Gatsby's cache
      store, // Gatsby's Redux store
    })
    // if the file was created, attach the new node to the parent node
    if (fileNode) {
      node.image___NODE = fileNode.id
    }
  }
}

这在运行 gatsby developgatsby build 时似乎正常工作,但如果我尝试再次运行这些命令(使用相同的源数据),则会引发以下错误:
Missing onError handler for invocation 'building-schema', 
error was Invariant Violation: Encountered an error 
trying to infer a GraphQL type for: `image___NODE`. 
There is no corresponding node with the `id` field matching: 

"27564a59-be49-51fb-98d6-c32de4f2030c",
"379357c0-1faa-5177-806d-7f155f2e3e85",

...

那些27564a59-b..379357c0-1..是在gatsby-node.js函数中创建的图像节点ID。

如果我运行gatsby clean,它将正常工作,但使用gatsby clean不是一个好的解决方案,因为清除缓存会破坏增量构建

有人知道如何解决这个错误吗?我应该为节点使用固定的ID吗?

Traceback错误:

(/my-project/node_modules/invariant/invariant.js:40:15)
    at getFieldConfigFromFieldNameConvention (/my-project/node_modules
/gatsby/src/schema/infer/add-inferred-fields.js:227:3)
    at getFieldConfig (/my-project/node_modules/gatsby/src/schema/infe
r/add-inferred-fields.js:129:19)
    at forEach (/my-project/node_modules/gatsby/src/schema/infer/add-i
nferred-fields.js:79:25)
    at Array.forEach (<anonymous>)
    at addInferredFieldsImpl (/my-project/node_modules/gatsby/src/sche
ma/infer/add-inferred-fields.js:63:28)
    at addInferredFields (/my-project/node_modules/gatsby/src/schema/i
nfer/add-inferred-fields.js:27:3)
    at addInferredType
(/my-project/node_modules/gatsby/src/schema/infer/index.js:101:3)
    at map
(/my-project/node_modules/gatsby/src/schema/infer/index.js:65:5)
    at Array.map (<anonymous>)
    at addInferredTypes
(/my-project/node_modules/gatsby/src/schema/infer/index.js:64:23)
    at updateSchemaComposer
(/my-project/node_modules/gatsby/src/schema/schema.js:169:9)
    at buildSchema
(/my-project/node_modules/gatsby/src/schema/schema.js:64:3)
    at build
(/my-project/node_modules/gatsby/src/schema/index.js:105:18)
    at buildSchema
(/my-project/node_modules/gatsby/src/services/build-schema.ts:19:3)'

你最终解决了这个问题吗? - Kevmon
并不是这样,我已经尝试使用固定的ID和createNodeId: id => Image${node.pk},但仍然抛出不变错误。 - Ander
我有同样的问题。你解决了这个问题吗? - coinhndp
1个回答

0

这似乎是一个在GitHub线程上比较新的话题。

如果清除缓存不适用于您的用例,那么问题似乎可以通过从npm转移到yarn作为依赖管理器来解决。

此外,还可以尝试通过以下方式删除所有node_modules和锁定的依赖项:

rm -rf node_modules && rm -rf package-lock.json

进行全新安装。


根据提示的错误,我建议尝试在节点创建的代码中加入try/catch语句块来解决问题。
// gatsby-node.js
const { createRemoteFileNode } = module.require(`gatsby-source-filesystem`)

exports.onCreateNode = async ({   node,
  actions: { createNode },
  store,
  cache,
  createNodeId,
 }) => {
  let fileNode;
 try{
  if (node.internal.type === `API__images` && node.pk) {
    fileNode = await createRemoteFileNode({
      url: node.url, // string that points to the URL of the image
      parentNodeId: node.id, // id of the parent node of the fileNode you are going to create
      createNode, // helper function in gatsby-node to generate the node
      createNodeId, // helper function in gatsby-node to generate the node
      cache, // Gatsby's cache
      store, // Gatsby's Redux store
    })
  } catch (e) {
      console.log(e)
    }
    // if the file was created, attach the new node to the parent node
    if (fileNode) {
      node.image___NODE = fileNode.id
    }
  }
}

我知道你说运行 gatsby clean 不是一个选项,但当你改变核心节点时,你可能被迫运行它。一旦你的项目完成(第一次构建),下一次构建将获取并使用你的缓存。


1
我已经在使用Yarn作为依赖管理器@Ferran Buireu(我已更新问题)。我已经尝试了你的建议,但是并没有解决这个问题。虽然如此,非常感谢你在Stackoverflow上的评论,在许多场合下帮我节省了大量时间。 - Ander
感谢您的反馈:)。如果答案没有提供任何有用的解决方法,我将删除它。以防万一...您尝试更新Node版本了吗?看起来您正在使用比较旧的版本(最新的LTS是14.17)。 - Ferran Buireu
是的,抱歉,我使用的是 Node v16.0.0,我不小心输入了 npm --version - Ander
你尝试过在节点创建中使用 try/catch 吗?(因为有 onError - Ferran Buireu
使用 createNodeId: id => 'Image${node.image_id}' 定义了固定的 ID,但是仍然出现了相同的错误:没有与 "id" 字段匹配的相应节点:"Image95,Image96 ... - Ander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接