You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 14使用Plaiceholder生成远程图片模糊占位符报错

Next.js 14 + Plaiceholder: "require is not defined" Error with Sharp

技术栈

{
  "@plaiceholder/next": "^3.0.0",
  "next": "^14.0.1",
  "plaiceholder": "^3.0.0",
  "react": "^18.2.0",
  "react-dom": "^18.2.0",
  "sharp": "^0.32.6"
}

需求

实现构建阶段生成的图片模糊加载效果,通过Plaiceholder生成base64格式的模糊占位符。

当前配置

next.config.mjs(ESM格式)

// @ts-check
import withPlaiceholder from "@plaiceholder/next";
 
/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
    images: {
        deviceSizes: [376, 480, 600, 768, 900, 1024, 1200, 1300],
        formats: ['image/webp'],
        remotePatterns: [
            {
                protocol: 'https',
                hostname: 'media.graphcms.com',
                pathname: '**',
            },
            {
                protocol: 'https',
                hostname: 'media.graphassets.com',
                pathname: '**',
            }
        ],
    }
}
 
export default withPlaiceholder(nextConfig);

工具函数 @/utils/useBlurImageData.ts

import { getPlaiceholder } from "plaiceholder";

export default async function useBlurImageData(imageUrl: string) {
  try {
    const buffer = await fetch(imageUrl).then(async (res) => {
      return Buffer.from(await res.arrayBuffer());
    });
    const { base64 } = await getPlaiceholder(buffer);

    return base64;
  } catch (err) {
    console.error(err);
  }
}

错误信息

运行时在 .next/static/chunks/app/events/page.js 第18行报错,对应代码:

"use strict";
module.exports = require("sharp");

错误提示:@plaiceholder/next 要求 next.config.js 为CommonJS模块而非ESM模块,使用ESM会导致 require is not defined。

已尝试的无效方案

  • 降级至Next.js 13
  • 更换配置文件后缀
  • 手动修改生成代码中的require为import

解决步骤

1. 切换next.config为CommonJS格式

把next.config.mjs重命名为next.config.js,并修改为CommonJS语法:

// @ts-check
const withPlaiceholder = require("@plaiceholder/next");
 
const nextConfig = {
    images: {
        deviceSizes: [376, 480, 600, 768, 900, 1024, 1200, 1300],
        formats: ['image/webp'],
        remotePatterns: [
            {
                protocol: 'https',
                hostname: 'media.graphcms.com',
                pathname: '**',
            },
            {
                protocol: 'https',
                hostname: 'media.graphassets.com',
                pathname: '**',
            }
        ],
    }
}
 
module.exports = withPlaiceholder(nextConfig);

2. 把占位符生成移到构建/服务器端

当前工具函数是在客户端运行时拉取图片生成base64,既不符合“构建阶段完成”的需求,也容易引发运行时问题。改成在服务器组件或静态生成阶段预生成:

import Image from 'next/image';
import { getPlaiceholder } from 'plaiceholder';

async function EventPage() {
  // 从数据源获取图片URL
  const imageUrl = "https://media.graphassets.com/your-image-path";
  
  // 在构建/请求时生成base64(非客户端运行时)
  const res = await fetch(imageUrl);
  const buffer = await res.arrayBuffer();
  const { base64 } = await getPlaiceholder(Buffer.from(buffer));

  return (
    <Image
      src={imageUrl}
      alt="Event Cover"
      width={1024}
      height={768}
      placeholder="blur"
      blurDataURL={base64}
    />
  );
}

export default EventPage;

3. 重新安装sharp确保依赖正常

如果仍有报错,先卸载再重装sharp:

npm uninstall sharp
npm install sharp

问题根源

@plaiceholder/next v3.0.0的内部实现依赖CommonJS模块加载逻辑,处理sharp时使用了require语法。而ESM格式的next.config(.mjs)环境中不存在require全局变量,因此触发报错。必须切换回CommonJS格式的配置文件才能解决。


内容的提问来源于stack exchange,提问作者tom curphey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 16:07:50