reactjs - 如何在 NetlifyCMS 构建中修复“TypeError:childImageSharp 未定义”?
问题描述
我正在现有的 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 上重新部署时收到这些错误。
配置.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"}
盖茨比-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
}
})
})
}
盖茨比-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 站点会轻而易举,但这是我尝试过的最困难的事情之一。
很感谢任何形式的帮助。
谢谢
解决方案
对我来说有几件事很奇怪。
您的查询不起作用(因此,破坏了代码),因为它找不到您的图像。
config.yml
将您的媒体路径更改为:media_folder: static/img public_folder: /img
注意路径中的斜杠 (
/
) 。public_folder
这是因为它是相对路径并且必须以斜杠开头。来自 Netlify 文档(斜线部分加粗):
公共文件夹
此设置是必需的。
该
public_folder
选项指定将访问媒体库上传的文件的文件夹路径,相对于构建站点的基础。对于由 [file] 或 [image] 小部件控制的字段,通过将此路径添加到所选文件的文件名来生成字段的值。默认为 media_folder 的值, 如果尚未包含,则打开/
。public_folder: "/images/uploads"
根据上述设置,如果用户使用名为的图像小部件字段
avatar
上传并选择名为的图像philosoraptor.png
,则该图像将保存到存储库中/static/img/philosoraptor.png
,并且文件的头像字段将设置为/img/philosoraptor.png
。
你media_folder
看起来不错。
<figure>
您在标签内渲染图像的方式。按照您的方法,它将呈现一个带有图像路径的字符串,但是,您正在使用Sharp fromgatsby-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
。您正在使用 a
staticQuery
但您不需要它,因为您的所有数据都来自 CMS。您应该使用页面/模板查询来提高性能,但这会改变您的页面结构。在 Gatsby 中创建动态页面的“标准”方式是
gatsby-node.js
使用createPage
API,将所需的数据传递给模板(通常是id
orslug
)并使用该唯一数据来检索博客/帖子信息。您正在传递
slug
via 上下文,但您从未使用它: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 playground) 来检查它。您的片段将无法在其中工作,因为它是 GraphQL 的限制,但它可以在您的代码上工作,因此请避免在此处使用它,但将其保留在您的代码中。
推荐阅读
- c# - Grpc - 从一个客户端向连接到同一服务器的另一个客户端发送消息
- loops - 在 Pyspark 中循环导致 sparkException
- java - 如何使用 java 将数据从 blob 数据类型从 oracle 迁移到 SQL 在文件流中我只动态发送表
- angular - 在 Angular CLI 中使用 ng new 命令出错
- reactjs - React-picky:元素类型无效:期望字符串(对于内置组件)或类/函数(对于复合组件)但得到:未定义
- java - 为什么 Jackson TypeReference 是抽象的?
- r - 将反应值从服务器传递到闪亮的ui中的两个条件面板(未嵌套)?
- android - 领域 - 在查询构建时访问字段名称而无需硬编码
- git - git push 没有任何问题
- python - 我应该如何使用 numpy 比较两个列表中每个位置的元素?