GraphQL 忽略了一些(但不是全部)任意分配的 markdown frontmatter 数据
GraphQL ignores some (but not all) arbitrarily assigned markdown frontmatter data
第一次尝试 Gatsby,很高兴。但是我 运行 遇到了一个 st运行ge GraphQL 问题:
我正在使用 gatsby-source-filesystem 和 gatsby-t运行sformer-remark 插件从降价文件中提取内容。
前言数据在所有这些中都不相同(title
除外)。有些有一个 date
字符串(博客文章),同样有一个 tag
数组,有些有一个 gallery
对象。
现在的问题是,一些这种任意分配的 frontmatter 数据在 GraphQL 中可用,而另一些则不可用。例如,如果我尝试查询日期,我总是得到 "GraphQL Error Unknown field date
on type frontmatter_2
"。而如果我查询标签,我会得到那些包含一个标签的项目的标签数组,而 tags: null
则为那些不包含标签的项目。
这里有什么问题?我怎样才能始终获得 null
作为节点中不存在的字段的值?
可能值得注意的是,此行为会根据我的降价文件的目录结构而变化。如果我四处移动它们,GraphQL 中的一些 frontmatter 字段将变得可用,而以前这些字段是不可用的,反之亦然。还会发生在通过 HMR 推送一些代码更改后,一些字段变得可用 - 但在我重新启动 Gatsby 之后,尽管没有触及中间的代码,它们又消失了。
非常感谢您的帮助!
编辑:
经过一段时间的努力没有成功,我求助于确保所有 markdown frontmatter 具有相同类型的相同字段。
我猜
TODO link to docs on auto-inferring types/fields.
部分documentation是关于这个问题的。
当我有更多时间时,我想了解更多关于 GraphQL 及其在 Gatsby 中的工作原理。任何指点表示赞赏。
您可能遇到了 this 错误,有时 GraphQL 似乎遗漏了稀疏填充的字段。
但是,要回答您的具体问题,您如何才能确保始终为空字段获得 null
。您可以使用 onCreateNode
挂钩来做到这一点。每个节点都会调用此挂钩。
类似于以下伪代码的内容将实现您的目标:
exports.onCreateNode = ({node, getNode, boundActionCreators}) => {
const { createNodeField } = boundActionCreators
if (_.get(node, 'internal.type') === `MarkdownRemark`) {
// Repeat this for each field
createNodeField({
node,
name: 'date',
value: _.get(node, 'frontmatter.date', 'default date'),
})
}
}
这会将值从 frontmatter
复制到 fields
并确保它们始终存在并带有一些默认值(如果它们不存在)。您可以在 node.internal.type
上添加测试以过滤特定节点类型
注意:这是完全未经测试的,即兴的伪代码,使用风险自负!
第一次尝试 Gatsby,很高兴。但是我 运行 遇到了一个 st运行ge GraphQL 问题:
我正在使用 gatsby-source-filesystem 和 gatsby-t运行sformer-remark 插件从降价文件中提取内容。
前言数据在所有这些中都不相同(title
除外)。有些有一个 date
字符串(博客文章),同样有一个 tag
数组,有些有一个 gallery
对象。
现在的问题是,一些这种任意分配的 frontmatter 数据在 GraphQL 中可用,而另一些则不可用。例如,如果我尝试查询日期,我总是得到 "GraphQL Error Unknown field date
on type frontmatter_2
"。而如果我查询标签,我会得到那些包含一个标签的项目的标签数组,而 tags: null
则为那些不包含标签的项目。
这里有什么问题?我怎样才能始终获得 null
作为节点中不存在的字段的值?
可能值得注意的是,此行为会根据我的降价文件的目录结构而变化。如果我四处移动它们,GraphQL 中的一些 frontmatter 字段将变得可用,而以前这些字段是不可用的,反之亦然。还会发生在通过 HMR 推送一些代码更改后,一些字段变得可用 - 但在我重新启动 Gatsby 之后,尽管没有触及中间的代码,它们又消失了。
非常感谢您的帮助!
编辑:
经过一段时间的努力没有成功,我求助于确保所有 markdown frontmatter 具有相同类型的相同字段。
我猜
TODO link to docs on auto-inferring types/fields.
部分documentation是关于这个问题的。
当我有更多时间时,我想了解更多关于 GraphQL 及其在 Gatsby 中的工作原理。任何指点表示赞赏。
您可能遇到了 this 错误,有时 GraphQL 似乎遗漏了稀疏填充的字段。
但是,要回答您的具体问题,您如何才能确保始终为空字段获得 null
。您可以使用 onCreateNode
挂钩来做到这一点。每个节点都会调用此挂钩。
类似于以下伪代码的内容将实现您的目标:
exports.onCreateNode = ({node, getNode, boundActionCreators}) => {
const { createNodeField } = boundActionCreators
if (_.get(node, 'internal.type') === `MarkdownRemark`) {
// Repeat this for each field
createNodeField({
node,
name: 'date',
value: _.get(node, 'frontmatter.date', 'default date'),
})
}
}
这会将值从 frontmatter
复制到 fields
并确保它们始终存在并带有一些默认值(如果它们不存在)。您可以在 node.internal.type
上添加测试以过滤特定节点类型
注意:这是完全未经测试的,即兴的伪代码,使用风险自负!