簡體   English   中英

在 Next.js / Webpack 5 中安裝 Plaiceholder 導致:找不到模塊:無法解析“child_process”

[英]Installing Plaiceholder in Next.js / Webpack 5 causes: Module not found: Can't resolve 'child_process'

我正在 Next.js 應用程序上構建,當我安裝/導入Plaiceholder (用於生成占位符圖像)時,出現以下錯誤: Module not found: Can't resolve 'child_process'

  • 節點 v14.18.0
  • Next.js v11.1.2
  • 占位符 v2.2.0
  • 夏普 v0.29.2

我理解此錯誤消息意味着 webpack5 正在嘗試捆綁客戶端無法使用的節點包。 但我不清楚它為什么這樣做。 我還沒有自定義任何 webpack 配置,並且在 Plaiceholder 文檔中找不到任何提及此問題的內容。 我如何解決它?

注意:我希望在構建期間創建 base64 數據 URL,以便在頁面加載后立即可用(不在運行時異步獲取)。

這是我的 next.config.js

module.exports = {
  reactStrictMode: true,
};

我的 package.json 只有scriptsdependenciesdevDependencies (沒有改變模塊分辨率)

如果它是相關的,這是一個使用 Plaiceholder 的簡化示例:

import Image from "next/image";
import { getPlaiceholder } from "plaiceholder";
import React, { useState } from "react";

...

const { base64 } = await getPlaiceholder(imgUrl);

...

return (<Image
            src={imgUrl}
            placeholder="blur"
            blurDataURL={base64}
          />);

似乎 plaiceholder 不適合客戶端渲染。 我相信該軟件包適用於 Node.js 環境。 這就是當您嘗試在客戶端呈現組件時出現此錯誤的原因。

要解決這個問題,您需要將import { getPlaiceholder } from 'plaiceholder'移動到 NextJS API 部分。 然后,您可以使用正文中的 URL 數據調用該 API。 然后得到base64。

/api/getBase64.js

import { getPlaiceholder } from "plaiceholder";

export default async (req, res) => {
  const { body } = req;
  const { url } = body;

  const { base64 } = getPlaiceholder(url);

  res.status(200).send(base64);
};

/component.js

import Image from "next/image";
import React, { useState, useEffect } from "react";

const [base64, setBase64] = useState()

useEffect(() => {
  (async () => {
   const _base64 = await fetch.post('/api/getBase64', {url: imgUrl}); // wrote for demonstration
   setBase64(_base64);
  })()
})

return (<Image
            src={imgUrl}
            placeholder="blur"
            blurDataURL={base64}
          />);

我知道blurDataURL在您獲取數據之前將是未定義的,但這是您可以使用plaiceholder庫來管理圖像的方式。 它應該只為 NodeJS 環境導入。 如果您不喜歡這種方法,您可以嘗試找到另一個也適用於瀏覽器環境(客戶端)的庫

根據評論更新:

如果要在構建時生成這個base64 ,可以在使用這個Image組件的頁面中使用getStaticProps NextJS 足夠聰明,可以了解客戶端或服務器端使用了哪些庫。 所以你可以這樣做:

import { getPlaiceholder } from "plaiceholder";  // place it at the root of file. This will not be bundled inside of client-side code

export async function getStaticProps(context) {
  const { base64 } = await getPlaiceholder(imgUrl);

  return {
    props: { base64 }, // will be passed to the page component as props
  }
}

這樣,通過使用getStaticProps ,頁面將在構建時創建。 您可以在使用圖像組件的頁面內獲取base64道具,並將該道具傳遞給blurDataURL 此外,您也可以將此方法與getServerSideProps一起使用。

這是來自 NextJS 網站:

注意:您可以導入頂級范圍內的模塊以在 getServerSideProps 中使用。 getServerSideProps 中使用的導入不會被捆綁到客戶端。

https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering

有必要為 Next Js 依賴安裝插件並根據Plaiceholder Docs配置下一個配置,以便在 getStaticProps 中使用 getPlaiceholder() 函數,就像@oakar 的回答一樣。

npm i @plaiceholder/next
const { withPlaiceholder } = require("@plaiceholder/next");


module.exports = withPlaiceholder({
    // your Next.js config
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM