我正在使用 GatsbyJS 构建一个网站。我在两个不同的文件夹中有 markdown 文件:/content/collections
and /content/posts
我希望 Gatsby 为每个 Markdown 文件创建一个页面,并使用相应的模板(collection.js 和 post.js)。
所以我在 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,
};
我尝试重构以下所有 gatsby-node.js 文件这个答案 https://stackoverflow.com/questions/64536170/how-to-create-multiple-page-types-dynamically-in-gatsby-node-js但我最终遇到了同样的情况。
我哪里理解错了?