简体   繁体   English

使用 Next.js 中的 getStaticProps 对来自公共文件夹的 static 图像进行编码

[英]Encoding static imagery from public folder using getStaticProps in Next.js

Next.js lays out a pretty comprehensive way to get imagery from the /public/ folder (where the app has you store static assets). Next.js 提供了一种从/public/文件夹(应用程序让您存储 static 资产)获取图像的非常全面的方法 The pattern is to use fs from Node and do the fetch in getStaticProps .该模式是使用 Node 中的fs并在getStaticProps中进行获取。

My attempt:我的尝试:

export async function getStaticProps({ params, preview = false, previewData }) {
  const cityData = dataFiltered.find( city => city.citySlug === params.slug )
  const cityMapImagePath = path.join(process.cwd(), `/public/static-maps/${cityData.imgPath}`)
  const cityMapImageRes = await fs.readFile(cityMapImagePath)
  const cityMapImageProcessed = JSON.stringify(cityMapImageRes)

  return {
    props: {
      preview,
      cityData: cityData,
      cityMapImage: cityMapImageProcessed
    },
    revalidate: 60,
  };
}

This code works, but it returns a pretty weird response when I reference that object in my component:此代码有效,但是当我在我的组件中引用 object 时,它会返回一个非常奇怪的响应:

<img src="{ "type":"Buffer", "data":[255,216,255,224,0,6,75,56,86,87,...] } />

My error has something to do with how I'm processing what fs gives me back.我的错误与我如何处理fs给我的东西有关。 Do I need to encode my jpeg into base64 to get Next to use it?我是否需要将我的 jpeg 编码为base64才能让 Next 使用它? This answer suggests stringifying and then parsing (didn't work for me).这个答案建议字符串化然后解析(对我不起作用)。 Or maybe I need a full blown endpoint to do this?或者也许我需要一个完整的端点来做到这一点? Next isn't very clear on how to get imagery from getStaticProps into the component above it - perhaps you know how? Next 不是很清楚如何将图像从 getStaticProps 获取到它上面的组件中——也许你知道怎么做?

All data that is returned from the getStaticProps needs to be JSON serializable, so yes, if you want to return image there, you need to base64 encode it (this can be a problem for big images).getStaticProps返回的所有数据都需要是 JSON 可序列化的,所以是的,如果你想在那里返回图像,你需要 base64 对其进行编码(这可能是大图像的问题)。 The other solution (if the scenario permits it) is not to do it with getStaticProps rather load the image on demand in the front end, by hitting the API after the page has already loaded.另一种解决方案(如果场景允许)不是使用getStaticProps来执行此操作,而是在页面加载后通过点击 API 在前端按需加载图像。

What I ended up doing for the fetch in getStaticProps :我最终为getStaticProps中的 fetch 做了什么:

export async function getStaticProps({ params, preview = false, previewData }) {
  const cityData = dataFiltered.find( city => city.citySlug === params.slug )
  const cityMapImagePath = path.join(process.cwd(), `/public/static-maps/${cityData.imgPath}`)
  let cityMapImageRes, cityMapImageProcessed

  try {
    cityMapImageRes = await fs.readFile(cityMapImagePath)
    cityMapImageProcessed = Buffer.from(cityMapImageRes).toString('base64')
  } catch {
    cityMapImageProcessed = null
  }

  return {
    props: {
      preview,
      cityData: cityData,
      cityMapImage: cityMapImageProcessed
    },
    revalidate: 60,
  };
}

Also make sure up in the component, you are properly encoding your image source as base64 with the data:image/png;base64, prefix.还要确保在组件中,您正确地将图像源编码为base64并带有data:image/png;base64,前缀。 This was a silly mistake that cost me an hour of debugging:这是一个愚蠢的错误,花了我一个小时的调试时间:

<img src={`data:image/png;base64,${cityMapImage}`} alt='Alt text here' />

Finally, also note that Next.js when used with Vercel will impose a hard, 50MB cap (compressed) on the serverless function used to process your page file request.最后,还要注意 Next.js 与 Vercel 一起使用时,将对用于处理page文件请求的无服务器 function 施加一个硬的 50MB 上限(压缩) If you're doing a [slug].js template, all the assets for EVERY page generated will count towards that cap.如果您正在使用[slug].js模板,则生成的每个页面的所有资产都将计入该上限。 You'll hit it pretty fast on deploy, so double check yourself.你会在部署时很快击中它,所以请仔细检查自己。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM