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
相关产品推荐
相关产品推荐

