使用 Next.js 中的 getStaticProps 对 public 文件夹中的静态图像进行编码

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

Next.js lays out a pretty comprehensive way/public/ 文件夹(应用程序让您存储静态资产的位置)获取图像。该模式是使用来自 Node 的 fs 并在 getStaticProps.

中进行提取

我的尝试:

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,
  };
}

此代码有效,但当我在我的组件中引用该对象时,它 returns 一个非常奇怪的响应:

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

我的错误与我处理 fs 返回的内容的方式有关。我是否需要将我的 jpeg 编码为 base64 才能让 Next 使用它? This answer suggests stringifying and then parsing (didn't work for me). Or maybe I need a 要做到这一点?接下来不是很清楚如何从 getStaticProps 获取 imagery 到它上面的组件 - 也许你知道怎么做?

getStaticProps 中 return 编辑的所有数据都需要 JSON 可序列化,所以是的,如果你想在那里 return 图像,你需要base64 对其进行编码(这对于大图像来说可能是个问题)。 另一种解决方案(如果情况允许)不是使用 getStaticProps 而是在前端按需加载图像,方法是在页面加载后点击 API。

我最终为 getStaticProps 中的提取做了什么:

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,
  };
}

还要确保在组件中,您正确地将图像源编码为带有 data:image/png;base64, 前缀的 base64。这是一个愚蠢的错误,花费了我一个小时的调试时间:

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

最后,还要注意 Next.js 与 Vercel 一起使用时会强加一个硬 50MB cap (compressed) on the serverless function 用于处理您的 page 文件请求。如果您正在制作 [slug].js 模板,则生成的每个页面的所有资产都将计入该上限。你会在部署时很快地击中它,所以仔细检查你自己。