如何在 NetlifyCMS 构建中修复“TypeError:childImageSharp 未定义”?
Posted
技术标签:
【中文标题】如何在 NetlifyCMS 构建中修复“TypeError:childImageSharp 未定义”?【英文标题】:How do I fix "TypeError: childImageSharp is undefined" on NetlifyCMS build? 【发布时间】:2021-02-16 14:26:50 【问题描述】:我正在现有的 gatsby 网站上设置一个简单的博客页面,我希望使用 netlify cms 的人能够为博客文章上传缩略图。我已经设法这样做并使用 graphigl 找到它
现在我想将它设置到我的博客文章页面:
import React from "react"
import Link, graphql, useStaticQuery from "gatsby"
import Layout from "../components/layout/layout"
const Blog = () =>
const data = useStaticQuery(graphql`
query
allMarkdownRemark
edges
node
frontmatter
title
date
thumbnail
childImageSharp
fluid(maxWidth: 400)
src
fields
slug
`)
return (
<>
<Layout>
<main className="main">
<div className="articles">
<h1 className="articles__title">Articles</h1>
data.allMarkdownRemark.edges.map(edge =>
return (
<section className="articles__list">
<a className="articles__article">
<div className="articles__article-artwork">
<figure className="articles__article-artwork-wrapper">
edge.node.frontmatter.thumbnail.childSharpImage.fluid.src
</figure>
</div>
<h2 className="articles__article-title">
<Link to=`/blog/$edge.node.fields.slug`>
edge.node.frontmatter.title
</Link>
</h2>
<Link>
<p>edge.node.frontmatter.date</p>
</Link>
<div className="articles__article-description">
<p></p>
</div>
<span className="articles__article-more">Read more...</span>
</a>
</section>
)
)
</div>
</main>
</Layout>
</>
)
export default Blog
然后在 netlify 上重新部署时出现这些错误。
config.yml
backend:
name: github
branch: development
repo: (removed for work reasons)
media_folder: static/img
public_folder: img
collections:
- name: "blog"
label: "Blog"
folder: "src/posts"
create: true
slug: "slug"
fields:
- label: "Layout", name: "layout", widget: "hidden", default: "blog"
- label: "Title", name: "title", widget: "string"
- label: "Publish Date", name: "date", widget: "datetime"
- label: "Body", name: "body", widget: "markdown"
- label: "Image", name: "thumbnail", widget: "image"
gatsby-node.js
const path = require('path')
module.exports.onCreateNode = ( node, actions ) =>
const createNodeField = actions
if (node.internal.type === "MarkdownRemark")
const slug = path.basename(node.fileAbsolutePath, '.md')
createNodeField(
node,
name: 'slug',
value: slug
)
module.exports.createPages = async ( graphql, actions) =>
const createPage = actions
const blogTemplate = path.resolve('./src/templates/blog.js')
const res = await graphql(`
query
allMarkdownRemark
edges
node
fields
slug
`)
res.data.allMarkdownRemark.edges.forEach((edge) =>
createPage(
component: blogTemplate,
path: `/blog/$edge.node.fields.slug`,
context:
slug: edge.node.fields.slug
)
)
gatsby-config.js
module.exports =
siteMetadata:
title: `removed for work reasons`,
description: `removed`,
author: `removed`,
,
plugins: [
`gatsby-plugin-react-helmet`,
`gatsby-plugin-sass`,
`gatsby-plugin-remove-serviceworker`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
resolve: `gatsby-source-filesystem`,
options:
name: `images`,
path: `$__dirname/src/images`,
,
,
resolve: `gatsby-source-filesystem`,
options:
name: `img`,
path: `$__dirname/static/img`,
,
,
resolve: `gatsby-source-filesystem`,
options:
name: `src`,
path: `$__dirname/src`,
,
,
resolve: `gatsby-plugin-manifest`,
options:
name: `gatsby-starter-default`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
,
,
resolve: 'gatsby-plugin-react-svg',
options:
rule:
include: /assets/
,
resolve: `gatsby-transformer-remark`,
options:
plugins: [
resolve: `gatsby-remark-images`,
options:
maxWidth: 590,
,
resolve: `gatsby-plugin-netlify-cms-paths`,
options:
cmsConfig: `/static/admin/config.yml`
]
,
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`,
`gatsby-plugin-netlify-cms`,
`gatsby-plugin-netlify`,
],
我真的认为使用 netlify cms 将博客页面添加到我现有的 gatsby 网站会轻而易举,但这是我尝试过的最困难的事情之一。
非常感谢任何帮助。
谢谢
【问题讨论】:
【参考方案1】:我觉得有些奇怪。
您的查询不起作用(因此,破坏了代码),因为它找不到您的图像。将您的 config.yml
媒体路径更改为:
media_folder: static/img
public_folder: /img
注意public_folder
路径中的斜杠 (/
)。
这是因为它是相对路径,必须以斜杠开头。 From Netlify docs(斜线部分加粗):
公共文件夹
此设置是必需的。
public_folder
选项指定文件所在的文件夹路径 由媒体库上传的将被访问,相对于基础 的建成网站。对于由 [file] 或 [image] 小部件控制的字段, 该字段的值是通过将此路径添加到 所选文件的文件名。默认为 media_folder 的值, 如果还没有包含一个开头/
。public_folder: "/images/uploads"
根据上述设置,如果用户使用了图像小部件字段 调用
avatar
上传并选择名为philosoraptor.png
的图像, 图像将保存到存储库中/static/img/philosoraptor.png
,以及头像字段 文件将设置为/img/philosoraptor.png
。
您的media_folder
看起来不错。
您在<figure>
标记内渲染图像的方式。按照您的方法,它将呈现一个带有图像路径的字符串,但是,您正在使用来自gatsby-image
的锐利,但您没有使用它。在一些试验中,我建议以下:
<figure>
<Img fluid=edges.node.frontmatter.thumbnail.childImageSharp.fluid>
</figure>
按照gatsby-image
方法,您还应该使用如下查询片段:
const data = useStaticQuery(graphql`
query
allMarkdownRemark
edges
node
frontmatter
title
date
thumbnail
childImageSharp
fluid(maxWidth: 400)
...GatsbyImageSharpFluid
fields
slug
`)
注意...GatsbyImageSharpFluid
片段以获取所有需要的数据以使用gatsby-image
。
您正在使用staticQuery
,但您不需要它,因为您的所有数据都来自 CMS。您应该使用page/template query 来提高性能,但这会改变您的页面结构。
在 Gatsby 中创建动态页面的“标准”方式是使用gatsby-node.js
来使用createPage
API,将所需数据传递给模板(通常是id
或slug
)并使用该唯一数据检索博客/帖子信息。
您正在通过上下文传递slug
,但您从未使用它:
context:
slug: edge.node.fields.slug
此外,您再次使用静态查询 (allMarkdownRemark
) 循环浏览所有文章,这没有意义,而且浪费时间和性能。
您的Blog
模板应如下所示:
import React from 'react'
import graphql from 'gatsby'
const Blog = (data) =>
return (
<div>
Blog title is: data.markdownRemark.frontmatter.title
</div>
)
export const query = graphql`
query BlogQuery($slug: String!)
query
markdownRemark(fields: slug: eq: $slug )
html
frontmatter
title
date
thumbnail
childImageSharp
fluid(maxWidth: 400)
...GatsbyImageSharpFluid
fields
slug
`
export default Blog
请注意,您将 slug ($slug
) 作为必需参数 (String!
) 传递,因此页面查询不能为 null。之后,您将过滤降价节点 (markdownRemark
) 以获取与您在 gatsby-node.js
文件中传递的上下文相匹配的节点。换句话说,在这种情况下,您拥有每个帖子的数据。
另外请注意,您可能需要更改查询以匹配您的数据结构,我是在不知道您的字段的情况下从头开始发布的。使用localhost:8000/___graphql
(GraphQL 操场)来检查它。您的 Fragment 无法在其中工作,因为它是 GraphQL 的限制,但它可以在您的代码上工作,因此请避免在其中使用它,但将其保留在您的代码中。
【讨论】:
谢谢伙计。所以这个页面是我的博客文章页面,我为实际的单个帖子制作了一个模板页面,我没有使用 staticQuery 而是只使用查询和 slug ,这是应该通过的地方。我做了一些更改,但我仍然无法让 childImageSharp 工作。现在我得到“无法在“文件”类型上查询字段“childSharpImage””。这太令人困惑了! 抱歉改成 childImageSharp。修正了错字,现在我回到“TypeError:无法读取未定义的属性'childImageSharp'” 实际上,我能够让图像在我的个人博客模板上工作,但在上面的博客文章页面上没有运气。仍然错误 TypeError: Cannot read property 'childImageSharp' of null以上是关于如何在 NetlifyCMS 构建中修复“TypeError:childImageSharp 未定义”?的主要内容,如果未能解决你的问题,请参考以下文章
升级到 NextJS 9.0 后如何修复 React Hooks?
正确地将第二个动态模板添加到 Gatsby/NetlifyCMS - 我哪里出错了?
如何修复以下 Django 错误:“类型:IOError”“值:[Errno 13] 权限被拒绝”
Gatsby 和 Netlify CMS 预览错误与渲染 StaticQuery
如何修复 Android 中偏移 YYY 处的 Unmarshalling unknown type code XXX?