第一次尝试 Gatsby ,很高兴。但是我遇到了一个奇怪的 GraphQL 问题:
我正在使用 gatsby-source-filesystem 和 gatsby-transformer-remark 插件从 markdown 文件中提取内容。
所有的frontmatter数据都不相同(title
除外)。有些有 date
字符串(博客文章),同样有 tag
数组,有些有 gallery
目的。
现在的问题是,这些任意分配的 frontmatter 数据中的一些在 GraphQL 中可用,而有些则不可用。例如,如果我尝试查询日期,我总是得到“GraphQL Error Unknown field date
on type frontmatter_2
”。而如果我查询标签,我会得到包含一个和 tags: null
的那些项目的标签数组。对于那些不这样做的人。
这里有什么问题?我怎么总能得到 null
作为节点中不存在的字段的值?
值得注意的是,这种行为会根据我的 Markdown 文件的目录结构而改变。如果我移动它们,GraphQL 中的一些 frontmatter 字段将变得可用,而以前不可用,反之亦然。还有一种情况是,在通过 HMR 推送一些代码更改后,一些字段变得可用 - 但在我重新启动 Gatsby 后,尽管没有触及中间的代码,它们又消失了。
非常感谢您的帮助!
编辑 :
在尝试了一段时间没有成功之后,我求助于确保所有 markdown frontmatter 具有相同类型的相同字段。
我猜是
TODO link to docs on auto-inferring types/fields.
documentation 的一部分是关于这个问题的。
当我有更多时间时,我想了解更多关于 GraphQL 以及它在 Gatsby 中的工作原理。任何指针表示赞赏。
最佳答案
您可能正在点击 this有时 GraphQL 似乎遗漏了稀疏填充的字段的错误。
但是,要回答您的具体问题,您如何确保始终获得 null
对于空字段。您可以使用 onCreateNode
来做到这一点。钩。每个节点都会调用这个钩子(Hook)。
类似以下伪代码的内容将实现您的目标:
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
上添加测试过滤特定节点类型注意:这是完全未经测试的,即开即用的伪代码,使用风险自负!
关于GraphQL 忽略了一些(但不是全部)任意分配的 markdown frontmatter 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45895597/