简体   繁体   English

在 Next.js / Webpack 5 中安装 Plaiceholder 导致:找不到模块:无法解析“child_process”

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

I'm building on Next.js app and when I install / import Plaiceholder (for generating placeholder images), I get the following error: Module not found: Can't resolve 'child_process'我正在 Next.js 应用程序上构建,当我安装/导入Plaiceholder (用于生成占位符图像)时,出现以下错误: Module not found: Can't resolve 'child_process'

  • Node v14.18.0节点 v14.18.0
  • Next.js v11.1.2 Next.js v11.1.2
  • Plaiceholder v2.2.0占位符 v2.2.0
  • Sharp v0.29.2夏普 v0.29.2

I understand this error message to mean that webpack5 is trying to bundle node packages that aren't available to the client.我理解此错误消息意味着 webpack5 正在尝试捆绑客户端无法使用的节点包。 But I'm not clear why it is doing this.但我不清楚它为什么这样做。 I haven't customized any of the webpack configs, and I can't find any mention of this issue in the Plaiceholder docs.我还没有自定义任何 webpack 配置,并且在 Plaiceholder 文档中找不到任何提及此问题的内容。 How do I fix it?我如何解决它?

NOTE: I want the base64 data URL to get created during the build, so that it available as soon as the page loads (not fetched asynchronously at run time).注意:我希望在构建期间创建 base64 数据 URL,以便在页面加载后立即可用(不在运行时异步获取)。

Here's my next.config.js这是我的 next.config.js

module.exports = {
  reactStrictMode: true,
};

My package.json only has scripts , dependencies , and devDependencies (nothing to change module resolution)我的 package.json 只有scriptsdependenciesdevDependencies (没有改变模块分辨率)

In case it's relevant, here's a simplified example using Plaiceholder:如果它是相关的,这是一个使用 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}
          />);

It seems like plaiceholder is not suitable for client-side rendering.似乎 plaiceholder 不适合客户端渲染。 I believe that package is for the Node.js environment.我相信该软件包适用于 Node.js 环境。 That's why you get this error when you try to render your component on the client side.这就是当您尝试在客户端呈现组件时出现此错误的原因。

To solve this problem, you need to move import { getPlaiceholder } from 'plaiceholder' to the NextJS API section.要解决这个问题,您需要将import { getPlaiceholder } from 'plaiceholder'移动到 NextJS API 部分。 Then you can call that API with your URL data in the body.然后,您可以使用正文中的 URL 数据调用该 API。 Then get the base64.然后得到base64。

/api/getBase64.js /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 /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}
          />);

I know blurDataURL will be undefined until you fetch the data but this is the way how you can use plaiceholder library to manage your images.我知道blurDataURL在您获取数据之前将是未定义的,但这是您可以使用plaiceholder库来管理图像的方式。 It should be imported only for the NodeJS environment.它应该只为 NodeJS 环境导入。 If you do not like this approach, you can try to find another library that also works for the browser environment (client)如果您不喜欢这种方法,您可以尝试找到另一个也适用于浏览器环境(客户端)的库

UPDATED according to the comment:根据评论更新:

If you want to generate this base64 at build time, you can use getStaticProps in the pages that use this Image component.如果要在构建时生成这个base64 ,可以在使用这个Image组件的页面中使用getStaticProps NextJS is smart enough to understand which libraries are used in the client-side or server-side. NextJS 足够聪明,可以了解客户端或服务器端使用了哪些库。 So you can do this:所以你可以这样做:

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

This way, by using getStaticProps , the page will be created at build time.这样,通过使用getStaticProps ,页面将在构建时创建。 You can get the base64 prop inside of the page that uses the image component and pass that prop to blurDataURL .您可以在使用图像组件的页面内获取base64道具,并将该道具传递给blurDataURL Also, you can use this approach with getServerSideProps too.此外,您也可以将此方法与getServerSideProps一起使用。

This is from NextJS website:这是来自 NextJS 网站:

Note: You can import modules in top-level scope for use in getServerSideProps.注意:您可以导入顶级范围内的模块以在 getServerSideProps 中使用。 Imports used in getServerSideProps will not be bundled for the client-side. getServerSideProps 中使用的导入不会被捆绑到客户端。

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

It's necessary to Install plugin for Next Js dependency and configure next config based on Plaiceholder Docs for using getPlaiceholder() function in getStaticProps like the answer by @oakar.有必要为 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.

相关问题 我正在尝试将 NPM package 作为插件注入到 Next.js 应用程序上,以避免出现“找不到模块:无法解析‘child_process’”错误 - I'm Trying to Inject An NPM package As A Plugin on A Next.js App to Avoid A "Module not found: Can't resolve 'child_process'" Error 未找到模块:无法解析“child_process”NextJS + Nightmare - Module not found: Can't resolve 'child_process' NextJS + Nightmare Next.js:找不到模块:无法解析“canvg” - Next.js: Module not found: Can't resolve 'canvg' Next.js 未找到中间件模块:无法解析“fs” - Next.js middleware Module not found: Can't resolve 'fs' 找不到模块:无法解析“fs”,Next.Js - Module not found: Can't resolve 'fs', Next.Js 无法解析模块xmlhttprequest中的“ child_process” - Can't Resolve “child_process” in module xmlhttprequest 找不到模块:使用 Electron React Boilerplate 时无法解析“child_process” - Module not found: Can't resolve 'child_process' while using Electron React Boilerplate 找不到模块:无法解析“child_process” - google-spreadsheet - Module not found: Can't resolve 'child_process' - google-spreadsheet 无法解析“child_process” - Can't resolve 'child_process' 未找到模块:无法在 next.js 项目中解析“../styles/global.css” - Module not found: Can't resolve '../styles/global.css' in an next.js project
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM