gpt4 book ai didi

javascript - 连接两个 gatsby 节点

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:40:19 30 4
gpt4 key购买 nike

所以,我正在使用 gatsby-mdx从 MDX 文件创建站点的插件。我想在 SitePage 对象和 Mdx 对象之间创建一个关联,这样我就可以对 SitePage 边缘执行一个 graphQL 查询以构建站点导航。

我的大部分代码都在 TypeScript 中,所以如果您想知道这些是什么鬼,请忽略任何类型注释。

我尝试过的事情

使用字段

我的第一个想法是使用 onCreateNode API,获取 MDX 节点,并使用 createNodeField 操作将其添加到 SitePage。一切正常,B-U-T gatsby-mdx 插件 adds a bunch of other info to their node稍后使用 setFieldsOnGraphQLNodeType API(在 onCreateNode API 之后发生)。我希望这些字段(例如 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') 传递,但也失败了。

使用父子链接

该插件使用 createParentChildLinkonCreateNode API 中创建文件节点和已解析的 MDX 节点之间的父子链接。操作 ( 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 property gatsby-mdx 添加到 Mdx 节点在 graphQL 查询中仍然不可用,例如:

{
allSitePage(filter: {fields: {childMdx: {id: {ne: null}}}}) {
edges {
node {
path
fields{
childMdx {
tableOfContents
fileAbsolutePath
frontmatter {
title
}
}
}
context {
roughFilePath
id
}
}
}
}
}

其他(可能不相关的)信息

我是 creating some pages programmatically在 gatsby-node.js 中。

我看到了类似用例的建议,可以使用 node type mappings ,但我认为 SitePage 和 MDX 对象之间的映射需要一些技巧(具体来说,从 siteMetadata 读取一些内容并进行字符串比较),我认为这不适用于我的用例。

最佳答案

所以我终于找到了一个更好的解决方案(比我之前的尝试,它涉及将 mdx 节点泵入页面的 context)。

Gatsby 有一个 undocumented method将节点相互链接:

Yes, you can can use createNodeField with the not-yet-documented ___NODE syntax to create links between nodes.

所以,步骤是这样的:

  • createPage中,将Mdx节点的id存入SitePage节点。
  • onCreateNode中,如果节点是SitePage,使用createNodeField,以Mdx___NODE作为字段名,Mdx节点的id 作为值。

我的gatsby-node.js:

const path = require("path")
const { createFilePath } = require("gatsby-source-filesystem")

exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions

if (node.internal.type === "SitePage" && node.context && node.context.id) {

createNodeField({
name: "Mdx___NODE",
value: node.context.id,
node,
})
}

if (node.internal.type === "Mdx") {
const value = createFilePath({ node, getNode })
createNodeField({
// 1) this is the name of the field you are adding,
name: "slug",
// 2) this node refers to each individual MDX
node,
value: `/blog${value}`
})
}
}


exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions;
const { data, errors } = await graphql(`
{
allMdx {
edges {
node {
id
fields {
slug
}
}
}
}
}
`)

if (errors) throw errors
data.allMdx.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve(`./src/components/posts-page-layout.js`),
context: { id: node.id }
});
});
};

结果:

graphiql

希望对您有所帮助!

关于javascript - 连接两个 gatsby 节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54203423/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com