【问题标题】:Programmatically create multiple types of pages in Gatsby.js在 Gatsby.js 中以编程方式创建多种类型的页面
【发布时间】:2021-02-12 01:47:51
【问题描述】:

我正在用 GatsbyJS 建立一个网站。我在两个不同的文件夹中有 Markdown 文件:/content/collections/content/posts,我希望 Gatsby 使用各自的模板(collection.js 和 post.js)为每个 markdown 文件创建一个页面。

所以我在我的 gatsby-node.js 文件中写了这个:

const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');
exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions;
  if (node.internal.type === 'MarkdownRemark') {
    const longSlug = createFilePath({ node, getNode, basePath: 'content' });
    const slug = longSlug.split('/');
    createNodeField({
      node,
      name: 'slug',
      value: `/${slug[slug.length - 2]}/`,
    });
  }
};

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const result = await graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "collections"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `);
  result.data.allFile.edges.forEach(({ node }) => {
    createPage({
      path: node.childMarkdownRemark.fields.slug,
      component: path.resolve('./src/templates/collection.js'),
      context: {
        slug: node.childMarkdownRemark.fields.slug,
      },
    });
  });
};

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const result = await graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "posts"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `);
  result.data.allFile.edges.forEach(({ node }) => {
    createPage({
      path: node.childMarkdownRemark.fields.slug,
      component: path.resolve('./src/templates/post.js'),
      context: {
        slug: node.childMarkdownRemark.fields.slug,
      },
    });
  });
};

认为它会起作用。它确实适用于我输入的第二种类型。(在这种情况下,它创建帖子,但不创建集合。如果我颠倒调用 createPages 的顺序,它会交换,但它永远不会创建所有这些)

这是我在控制台中遇到的错误:

warning The GraphQL query in the non-page component "/Users/matteocarpi/Documents/Web/Ledue/src/templates/collection.js" will not be run.
Exported queries are only executed for Page components. It's possible you're
trying to create pages in your gatsby-node.js and that's failing for some
reason.

If the failing component(s) is a regular component and not intended to be a page
component, you generally want to use a <StaticQuery> (https://gatsbyjs.org/docs/static-query)
instead of exporting a page query.

If you're more experienced with GraphQL, you can also export GraphQL
fragments from components and compose the fragments in the Page component
query and pass data down into the child component — https://graphql.org/learn/queries/#fragments

这两个模板非常相似:

import React from 'react';

import { graphql } from 'gatsby';
import PropTypes from 'prop-types';

const Post = ({data}) => {
  return (
    <div>
      <h1>{data.postData.frontmatter.title}</h1>
    </div>
  );
};

export default Post;

export const query = graphql`
query PostData($slug: String!) {
  postData: markdownRemark(fields: {slug: {eq: $slug}}) {
    frontmatter {
      title
    }
  }
}
`;

Post.propTypes = {
  data: PropTypes.node,
};
import React from 'react';

import { graphql } from 'gatsby';
import PropTypes from 'prop-types';

const Collection = ({data}) => {
  return (
    <div>
      <h1>{data.collectionData.frontmatter.title}</h1>
    </div>
  );
};

export default Collection;

export const query = graphql`
query CollectionData($slug: String!) {
  collectionData: markdownRemark(fields: {slug: {eq: $slug}}) {
    frontmatter {
      title
    }
  }
}
`;

Collection.propTypes = {
  data: PropTypes.node,
};

我尝试重构 this answer 之后的所有 gatsby-node.js 文件,但我最终遇到了同样的情况。

我哪里弄错了?

【问题讨论】:

    标签: javascript reactjs gatsby


    【解决方案1】:

    问题是你用第二个函数声明覆盖了你的第一个函数声明。有点像这样:

    var a = "hello"
    a = "world"
    

    相反,您应该对要在单个函数中创建的所有页面执行所有查询并调用 createPage,如下所示:

    exports.createPages = ({ graphql, actions }) => {
      const { createPage } = actions;
    
      const collections = graphql(`
        query {
          allFile(filter: {relativeDirectory: {eq: "collections"}}) {
            edges {
              node {
                childMarkdownRemark {
                  fields {
                    slug
                  }
                }
              }
            }
          }
        }
      `).then(result => {
        result.data.allFile.edges.forEach(({ node }) => {
          createPage({
            path: node.childMarkdownRemark.fields.slug,
            component: path.resolve('./src/templates/collection.js'),
            context: {
              slug: node.childMarkdownRemark.fields.slug,
            },
          });
        });
      })
    
      const posts = graphql(`
        query {
          allFile(filter: {relativeDirectory: {eq: "posts"}}) {
            edges {
              node {
                childMarkdownRemark {
                  fields {
                    slug
                  }
                }
              }
            }
          }
        }
      `).then(result => {
        result.data.allFile.edges.forEach(({ node }) => {
          createPage({
            path: node.childMarkdownRemark.fields.slug,
            component: path.resolve('./src/templates/post.js'),
            context: {
              slug: node.childMarkdownRemark.fields.slug,
            },
          });
        });
      })
    
      return Promise.all([collections, posts])
    };
    

    【讨论】:

    • 它昨天晚上工作...现在今天早上当我运行gatsby develop 时,我再次遇到昨天的相同错误...帖子页面没有创建...```警告非页面组件“/Users/matteocarpi/Documents/Web/Ledue/src/templates/post.js”中的 GraphQL 查询将不会运行。导出的查询仅对页面组件执行。您可能正在尝试在 gatsby-node.js 中创建页面,但由于某种原因而失败。等等...```
    • @MatteoCarpi 可能值得做gatsby clean 并重新启动gatsby develop
    • 是的,我正在这样做。我的错误更加愚蠢。我改变了一些路径并忘记了我做了...感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多