[英]gatsby.js: “node.frontmatter.image is null”
LAST EDIT: fixed.最后编辑:固定。 It was a naming convention.
这是一个命名约定。 I am currently using this tree structure:
我目前正在使用这种树结构:
-pages --posts ---00X-post For pagination/programmatically works fine so far. -pages --posts ---00X-post 到目前为止,分页/以编程方式工作正常。 And inside, md with its correspondent image (used as a thumbnail too).
在里面, md 及其对应的图像(也用作缩略图)。 One of those had the naming wrong.
其中一个名字有误。 Fixed.
固定的。 Now everything is working just fine.
现在一切正常。
EDIT and UPDATE:编辑和更新:
Thank you for your quick answer.谢谢你们的快速响应。 I tried that, nothing changed.
我试过了,没有任何改变。 I do believe it has to do with all the templates for pagination I am currently using.
我相信这与我目前使用的所有分页模板有关。 For example, the one in charge of creating page 2 and so in is this one:
例如,负责创建页面 2 等的是这个:
import React from 'react';
import Layout from '../components/layout';
import Post from '../components/Post';
import { graphql } from 'gatsby';
import { Row, Col } from 'reactstrap';
import Sidebar from '../components/Sidebar';
import PaginationLinks from '../components/PaginationLinks';
const postList = (props) => {
const posts = props.data.allMarkdownRemark.edges
const { currentPage, numberOfPages } = props.pageContext
return (
<Layout pageTitle>
<h1 className='titles'>{`page ${currentPage}`}</h1>
<Row>
<Col>
{posts.map(({node}) => (
<Post
key={node.id}
slug={node.fields.slug}
title={node.frontmatter.title}
author={node.frontmatter.author}
date={node.frontmatter.date}
body={node.excerpt}
tags={node.frontmatter.tags}
fluid={node.frontmatter.image.childImageSharp.fluid}
/>
))}
<PaginationLinks
currentPage={currentPage}
numberOfPages={numberOfPages}
/>
</Col>
<Col md='4'>
<Sidebar>
</Sidebar>
</Col>
</Row>
</Layout>
)
}
export const postListQuery = graphql`
query postListQuery($skip: Int!, $limit: Int!) {
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC}
limit: $limit
skip: $skip
) {
edges {
node {
id
frontmatter {
title
date
author
tags
image {
childImageSharp {
fluid(maxWidth: 650, quality: 90) {
...GatsbyImageSharpFluid
}
}
}
}
fields {
slug
}
excerpt
}
}
}
}
`
export default postList
Same error messages appear when creating pages by tags/authors.按标签/作者创建页面时会出现相同的错误消息。 If I delete the image field from the query, everything works.
如果我从查询中删除图像字段,一切正常。 This is unusual.
这是不寻常的。
While doing a simple blog project with Gatsby I run into either "TypeError: childImageSharp is undefined” or "node.frontmatter.image is null". This error message appears at random. By the time I started writing this, trying to access pages/2 only triggered it.在用 Gatsby 做一个简单的博客项目时,我遇到了“TypeError:childImageSharp is undefined”或“node.frontmatter.image is null”。此错误消息随机出现。当我开始写这篇文章时,试图访问页面/ 2只触发了它。
Here's index.js:这是 index.js:
import React from "react"
import { graphql, StaticQuery } from 'gatsby';
import Layout from "../components/layout"
import SEO from "../components/seo"
import Post from '../components/Post';
import Sidebar from '../components/Sidebar';
import { Row, Col } from 'reactstrap';
import PaginationLinks from '../components/PaginationLinks';
const IndexPage = () => {
const postsPerPage = 5;
let numberOfPages
return (
<Layout>
<SEO title="home" keywords={[`procedural`, `gatsby`]}/>
<h1 className='titles'>procedural</h1>
<Row>
<Col>
<StaticQuery
query={indexQuery}
render={data => {
numberOfPages = Math.ceil(
data.allMarkdownRemark.totalCount / postsPerPage
);
return (
<div>
{
data.allMarkdownRemark.edges.map(({ node }) => (
<Post
key={node.id}
title={node.frontmatter.title}
author={node.frontmatter.author}
date={node.frontmatter.date}
slug={node.fields.slug}
body={node.excerpt}
fluid={node.frontmatter.image.childImageSharp.fluid}
tags={node.frontmatter.tags}
/>
))
}
<PaginationLinks currentPage={1} numberOfPages={numberOfPages} />
</div>
)
}}
/>
</Col>
<Col md='4'>
<Sidebar>
</Sidebar>
</Col>
</Row>
</Layout>
)
}
const indexQuery = graphql`
query {
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC}
limit: 5
) {
totalCount
edges {
node {
id
frontmatter {
title
date
author
tags
image {
childImageSharp {
fluid(quality: 85, maxWidth: 960) {
...GatsbyImageSharpFluid
}
}
}
}
fields {
slug
}
excerpt
}
}
}
}
`
export default IndexPage
Here's gatsby-node.js:这是 gatsby-node.js:
const path = require('path');
const { slugify } = require('./src/utils/utilityFunctions');
const authors = require('./src/utils/authors');
const _ = require('lodash');
// single post generator
exports.onCreateNode = ({ node, actions }) => {
const { createNodeField } = actions
if(node.internal.type === 'MarkdownRemark') {
const slugFromTitle = slugify(node.frontmatter.title)
createNodeField({
node,
name: 'slug',
value: slugFromTitle,
})
}
}
exports.createPages = async ({ actions, graphql }) => {
const { createPage } = actions;
const templates = {
singlePost: path.resolve('./src/templates/single-post.js'),
tagsPage: path.resolve('./src/templates/tags-page.js'),
tagPosts: path.resolve('./src/templates/tag-post.js'),
postList: path.resolve('./src/templates/post-list.js'),
authorPosts: path.resolve('./src/templates/author-posts.js'),
}
const res = await graphql(`
{
allMarkdownRemark {
edges {
node {
frontmatter{
author
tags
}
fields {
slug
}
}
}
}
}
`)
if(res.errors) return Promise.reject(res.errors)
const posts = res.data.allMarkdownRemark.edges
posts.forEach(({node}) => {
createPage({
path: node.fields.slug,
component: templates.singlePost,
context: {
// passing slug, PENDING TAGS
slug: node.fields.slug,
// finding author imageUrl from authors.js and passing it to the single post template
},
})
})
// creating post pages
const postsPerPage = 5
const numberOfPages = Math.ceil(posts.length / postsPerPage)
Array.from({ length: numberOfPages }).forEach((_, index) => {
const isFirstPage = index === 0
const currentPage = index + 1
// skip first page and go to index.js
if (isFirstPage) return
createPage({
path: `/page/${currentPage}`,
component: templates.postList,
context: {
limit: postsPerPage,
skip: index * postsPerPage,
numberOfPages: numberOfPages,
currentPage: currentPage,
},
})
})
// tags PAGE GENERATOR; getting all tags
let tags = []
_.each(posts, edge => {
if (_.get(edge, 'node.frontmatter.tags')) {
tags = tags.concat(edge.node.frontmatter.tags)
}
})
// account of tags, we're putting them like this: ['design', 'example', 'luck'] and also {design: X, example: Y, luck: z}
let tagPostCounts = {}
tags.forEach(tag => {
tagPostCounts[tag] = (tagPostCounts[tag] || 0) + 1;
})
tags = _.uniq(tags) //elimninate all duplicate entries
// create tags page here
createPage({
path: `/tags`,
component: templates.tagsPage,
context: {
tags,
tagPostCounts,
}
})
// tag post page creation here:
tags.forEach(tag => {
createPage({
path: `/tag/${_.kebabCase(tag)}`,
component: templates.tagPosts,
context: {
tag
}
})
})
// CREATING PAGES FOR EACH AUTHOR'S POSTS:
authors.forEach(author => {
createPage({
path: `/author/${slugify(author.name)}`,
component: templates.authorPosts,
context: {
authorName: author.name,
imageUrl: author.imageUrl,
},
})
})
}
here's gatsby-config.js:这是 gatsby-config.js:
plugins: [
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-sass`,
`gatsby-transformer-remark`,
`gatsby-plugin-catch-links`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/pages`,
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `procedural`,
short_name: `procedural`,
start_url: `/`,
background_color: `#663399`, // PLACEHOLDER
theme_color: `#663399`, // PLACEHOLDER
display: `minimal-ui`, // PLACEHOLDER
icon: `src/images/logo.png`, // This path is relative to the root of the site.
},
},
],
And here's my single-post.js:这是我的 single-post.js:
import React from 'react';
import Layout from '../components/layout';
import { graphql, Link } from 'gatsby';
import SEO from '../components/seo';
import { Badge, Card, CardBody, CardSubtitle } from 'reactstrap';
import Img from 'gatsby-image';
import { slugify } from '../utils/utilityFunctions';
const SinglePost = ({ data, pageContext }) => {
const post = data.markdownRemark.frontmatter;
return (
<Layout>
<SEO title={post.title}/>
<h1 className='postTitles'>{post.title}</h1>
<Card>
<Img className='card-image-top' fluid={post.image.childImageSharp.fluid}>
</Img>
<CardBody className='cardBody'>
<CardSubtitle>
<span className='text-info'>
{post.date}
</span> by{' '}
<span className='text-info'>
{post.author}
</span>
</CardSubtitle>
<div dangerouslySetInnerHTML={{ __html: data.markdownRemark.html }}>
</div>
<ul className='post-tags'>
{
post.tags.map(tag => (
<li key={tag}>
<Link to={`/tag/${slugify(tag)}`}>
<Badge className='myTags'>{tag}</Badge>
</Link>
</li>
))
}
</ul>
<br/>
<Link
to={'/'}
className='myButton float-left'>
Go back
</Link>
</CardBody>
</Card>
<h3 className='text-center'>
Share this post
</h3>
<div className='text-center social-share-links'>
<ul>
<li>
<a href={'https://www.facebook.com/sharer/sharer.php?u=' + baseUrl +
pageContext.slug}
className='facebook' target='_blank'
rel='noopener noreferrer'>
<i className="fab fa-facebook-f fa-2x"/>
</a>
</li>
<li>
<a href={'https://www.twitter.com/share?url=' +
baseUrl +
pageContext.slug +
'&text=' +
post.title +
'&via' +
'twitterHandle'}
className='twitter' target='_blank'
rel='noopener noreferrer'>
<i className="fab fa-twitter fa-2x"/>
</a>
</li>
<li>
<a href={'https://www.plus.google.com/share?url' +
baseUrl +
pageContext.slug
}
className='google' target='_blank'
rel='noopener noreferrer'>
<i className="fab fa-google fa-2x"/>
</a>
</li>
<li>
<a href={'https://www.linkedin.com/shareArticle?url=' +
baseUrl +
pageContext.slug
}
className='linkedin' target='_blank'
rel='noopener noreferrer'>
<i className="fab fa-linkedin fa-2x"/>
</a>
</li>
</ul>
</div>
</Layout>
)
}
export const postQuery = graphql`
query blogPostBySlug($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
id
html
frontmatter {
title
author
date
tags
image {
childImageSharp{
fluid(quality: 100, maxWidth: 960) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
`
export default SinglePost;
Here's what happens when using gatsby develop:以下是使用 gatsby develop 时发生的情况:
$ gatsby develop
success open and validate gatsby-configs - 0.027s
success load plugins - 0.904s
success onPreInit - 0.031s
success initialize cache - 0.005s
success copy gatsby files - 0.081s
success onPreBootstrap - 0.014s
success createSchemaCustomization - 0.008s
success Checking for changed pages - 0.002s
success source and transform nodes - 0.126s
success building schema - 0.291s
info Total nodes: 110, SitePage nodes: 19 (use --verbose for breakdown)
success createPages - 0.061s
success Checking for changed pages - 0.001s
success createPagesStatefully - 0.087s
success update schema - 0.023s
success write out redirect data - 0.002s
success Build manifest and related icons - 0.103s
success onPostBootstrap - 0.109s
info bootstrap finished - 3.883s
success onPreExtractQueries - 0.002s
success extract queries from components - 0.419s
success write out requires - 0.027s
success run static queries - 0.030s - 2/2 65.79/s
success run page queries - 0.020s - 2/2 100.53/s
⠀
You can now view gatsby-starter-default in the browser.
⠀
http://localhost:8000/
⠀
View GraphiQL, an in-browser IDE, to explore your site's data and schema
⠀
http://localhost:8000/___graphql
⠀
Note that the development build is not optimized.
To create a production build, use gatsby build
⠀
success Building development bundle - 4.905s
Here's the error message when running gatsby build:这是运行 gatsby build 时的错误消息:
$ gatsby build
success open and validate gatsby-configs - 0.024s
success load plugins - 0.902s
success onPreInit - 0.047s
success delete html and css files from previous builds - 0.006s
success initialize cache - 0.004s
success copy gatsby files - 0.082s
success onPreBootstrap - 0.012s
success createSchemaCustomization - 0.008s
success Checking for changed pages - 0.001s
success source and transform nodes - 0.126s
success building schema - 0.276s
info Total nodes: 110, SitePage nodes: 19 (use --verbose for breakdown)
success createPages - 0.056s
success Checking for changed pages - 0.001s
success createPagesStatefully - 0.094s
success Cleaning up stale page-data - 0.006s
success update schema - 0.035s
success onPreExtractQueries - 0.003s
success extract queries from components - 0.499s
success write out redirect data - 0.002s
success Build manifest and related icons - 0.102s
success onPostBootstrap - 0.113s
info bootstrap finished - 5.462s
success run static queries - 0.021s - 2/2 96.19/s
success run page queries - 0.013s - 1/1 79.77/s
success write out requires - 0.005s
success Building production JavaScript and CSS bundles - 10.390s
success Rewriting compilation hashes - 0.003s
failed Building static HTML for pages - 2.388s
ERROR #95313
Building static HTML failed for path "/page/2"
See our docs page for more info on this error: https://gatsby.dev/debug-html
26 | body={node.excerpt}
27 | tags={node.frontmatter.tags}
> 28 | fluid={node.frontmatter.image.childImageSharp.fluid}
| ^
29 | />
30 | ))}
31 | <PaginationLinks
WebpackError: TypeError: Cannot read property 'childImageSharp' of null
- post-list.js:28
src/templates/post-list.js:28:55
- post-list.js:19
src/templates/post-list.js:19:24
You are using a page query in your IndexPage component, however, you are retrieving the data using a StaticQuery
component .您在 IndexPage 组件中使用 页面查询,但是,您正在使用
StaticQuery
组件检索数据。 Change it to:将其更改为:
import React from "react"
import { graphql, StaticQuery } from 'gatsby';
import Layout from "../components/layout"
import SEO from "../components/seo"
import Post from '../components/Post';
import Sidebar from '../components/Sidebar';
import { Row, Col } from 'reactstrap';
import PaginationLinks from '../components/PaginationLinks';
const IndexPage = ({data}) => {
const postsPerPage = 5;
let numberOfPages
return (
<Layout>
<SEO title="home" keywords={[`procedural`, `gatsby`]}/>
<h1 className='titles'>procedural</h1>
<Row>
<Col>
<div>
{
data.allMarkdownRemark.edges.map(({ node }) => (
{node.frontmatter.image && <Post
key={node.id}
title={node.frontmatter.title}
author={node.frontmatter.author}
date={node.frontmatter.date}
slug={node.fields.slug}
body={node.excerpt}
fluid={node.frontmatter.image.childImageSharp.fluid}
tags={node.frontmatter.tags}
/> }
))
}
<PaginationLinks currentPage={1} numberOfPages={numberOfPages} />
</div>
</Col>
<Col md='4'>
<Sidebar>
</Sidebar>
</Col>
</Row>
</Layout>
)
}
const indexQuery = graphql`
query {
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC}
limit: 5
) {
totalCount
edges {
node {
id
frontmatter {
title
date
author
tags
image {
childImageSharp {
fluid(quality: 85, maxWidth: 960) {
...GatsbyImageSharpFluid
}
}
}
}
fields {
slug
}
excerpt
}
}
}
}
`
export default IndexPage
The data fetched using pages queries, is stored under props
.使用页面查询获取的数据存储在
props
下。 Since in the snippet above you are destructuring props
as data
( ({data})
), you don't need to trigger another query like you were doing, your data is already stored in data
.由于在上面的代码段中,您将
props
解构为data
( ({data})
),因此您不需要像之前那样触发另一个查询,您的数据已经存储在data
中。 So you can loop it in the same way you were doing.所以你可以像以前一样循环它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.