所以,我正在使用盖茨比 mdx用于从 MDX 文件创建站点的插件。我想在 SitePage 对象和 Mdx 对象之间创建关联,以便我可以对 SitePage 边缘执行一个 graphQL 查询来构建站点导航。
我的大部分代码都是用 TypeScript 编写的,所以如果你想知道这些是什么 WTF,请忽略任何类型注释。
我尝试过的事情
使用字段
我的第一个想法是使用onCreateNodeAPI,获取 MDX 节点,然后使用以下命令将其添加到 SitePagecreateNodeField
行动。一切都很好,B-U-T gatsby-mdx 插件添加一堆其他信息到他们的节点稍后使用setFieldsOnGraphQLNodeTypeAPI(发生after the onCreateNode
应用程序编程接口)。我希望这些字段(例如 frontmatter 和 tableOfContents)在以后的 graphql 查询中可用,但他们没有使用此方法。
实施我自己的setFieldsOnGraphQLNodeType
我想我可以像 gatsby-mdx 扩展 Mdx 节点一样扩展 SitePage 对象。
我在这里遇到的关键问题是我无法弄清楚如何创建 Mdx GraphQL 节点类型。
export const setFieldsOnGraphQLNodeType = ({type, actions, getNodes}: any, pluginOptions: any) => {
if (type.name === "SitePage") {
const {createParentChildLink} = actions
return new Promise((resolve) => {
return resolve({
"childMdx": {
type: new GraphQLObjectType({
name: 'Mdx'
}),
async resolve(sitePageNode: any) {
const allNodes = getNodes()
if (sitePageNode.component &&
(sitePageNode.component.endsWith(".mdx") || sitePageNode.component === DefaultLayout)
) {
const associatedMdx = allNodes.find((mdxNode: any) =>
mdxNode.internal.type === 'Mdx' && mdxNode.fileAbsolutePath === sitePageNode.component
)
if (associatedMdx) {
console.log("Found associated MDX node", associatedMdx.id)
console.log("Adding it to the sitepage node", sitePageNode.id)
return associatedMdx
}
}
}
}
})
})
}
return {}
}
我还尝试简单地将类型作为字符串('Mdx')传递,但这也失败了。
使用父子链接
该插件在 File 节点和解析的 MDX 节点之间创建父子链接onCreateNode
API,使用创建父子链接行动 (source).
我尝试实施...
export const onCreateNode = ({node, actions, getNodes}: OnCreateNodeArgument) => {
const {createParentChildLink} = actions
const allNodes = getNodes()
if (node.internal && node.internal.type === 'SitePage' && node.component &&
(node.component.endsWith(".mdx") || node.component === DefaultLayout)
) {
const associatedMdx = allNodes.find((mdxNode: any) =>
mdxNode && mdxNode.internal && mdxNode.internal.type === 'Mdx' &&
(mdxNode.fileAbsolutePath === node.component || mdxNode.fileAbsolutePath === node.context.fileAbsolutePath)
)
if (associatedMdx) {
console.log("Found associated MDX node", associatedMdx.id)
console.log("Adding it to the sitepage node as a child", node.id)
createParentChildLink({parent: node, child: associatedMdx})
}
}
}
起初,这似乎成功了,但tableOfContents财产gatsby-mdx 添加到 Mdx 节点的信息在 graphQL 查询中仍然不可用,例如:
{
allSitePage(filter: {fields: {childMdx: {id: {ne: null}}}}) {
edges {
node {
path
fields{
childMdx {
tableOfContents
fileAbsolutePath
frontmatter {
title
}
}
}
context {
roughFilePath
id
}
}
}
}
}
其他(可能不相关)信息
I'm 以编程方式创建一些页面在 gatsby-node.js 中。
我看到了类似用例的建议节点类型映射,但由于 SitePage 和 MDX 对象之间的映射需要一些技巧(具体来说,从 siteMetadata 读取一些内容并进行字符串比较),我认为这不适用于我的用例。