在 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
- Plaiceholder v2.2.0
- 夏普 v0.29.2
我理解此错误消息的意思是 webpack5 正在尝试捆绑客户端无法使用的节点包。但我不清楚为什么要这样做。我没有自定义任何 webpack 配置,我在 Plaiceholder 文档中找不到任何关于这个问题的提及。我该如何解决?
注意:我希望在构建期间创建 base64 数据 URL,以便在页面加载后立即可用(而不是在 运行 时异步获取)。
这是我的 next.config.js
module.exports = {
reactStrictMode: true,
};
我的package.json只有scripts
、dependencies
和devDependencies
(没有改变模块分辨率)
如果相关,这里有一个使用 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 网站:
Note: You can import modules in top-level scope for use in
getServerSideProps. Imports used in getServerSideProps will not be
bundled for the client-side.
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
我正在构建 Next.js 应用程序,当我安装/导入 Plaiceholder(用于生成占位符图像)时,出现以下错误:Module not found: Can't resolve 'child_process'
- 节点 v14.18.0
- Next.js v11.1.2
- Plaiceholder v2.2.0
- 夏普 v0.29.2
我理解此错误消息的意思是 webpack5 正在尝试捆绑客户端无法使用的节点包。但我不清楚为什么要这样做。我没有自定义任何 webpack 配置,我在 Plaiceholder 文档中找不到任何关于这个问题的提及。我该如何解决?
注意:我希望在构建期间创建 base64 数据 URL,以便在页面加载后立即可用(而不是在 运行 时异步获取)。
这是我的 next.config.js
module.exports = {
reactStrictMode: true,
};
我的package.json只有scripts
、dependencies
和devDependencies
(没有改变模块分辨率)
如果相关,这里有一个使用 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 网站:
Note: You can import modules in top-level scope for use in getServerSideProps. Imports used in getServerSideProps will not be bundled for the client-side.
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering