Next.js + TypeScript项目图片无法显示问题求助
问题解决方法
1. 修复静态资源路径与动态导入错误
核心原因
你遇到的Cannot find module错误来自两个关键点:
- 路径规则错误:Next.js的
public文件夹是静态资源的根目录,引用其中的资源必须使用根相对路径(以/开头),而非组件间的层级相对路径(如../../../public/...)。 - 动态require限制:Next.js的静态构建工具无法解析动态生成的
require路径(比如require(button.icon)),它需要在构建阶段明确知晓所有要打包的资源。
具体修复步骤
步骤1:修正数组中的图标路径
将compButtonsArray里的icon字段改为根相对路径:
const compButtonsArray = [ { icon: '/icons/zavod.svg', label: 'Label 1', transitionDelay: '0s', countBtn: "discord-button" }, { icon: '/icons/gazprom.svg', label: 'Label 2', transitionDelay: '0.1s', countBtn: 'twitter-button' }, { icon: '/icons/ya.svg', label: 'Label 2', transitionDelay: '0.2s', countBtn: 'reddit-button' }, ];
步骤2:移除动态require,直接赋值src
Next.js的Image组件支持直接使用根相对路径作为src,无需require包裹。修改Button组件中的Image渲染逻辑:
{ companyButtons.map((button, index) => ( <button key={index} className={clsx(styles[`${button.countBtn}`], styles.button)} style={{ transitionDelay: `${button.transitionDelay}, ${button.transitionDelay}, ${button.transitionDelay}`, transitionProperty: 'translate, background, box-shadow' }} > <Image src={button.icon} alt={button.label} width={30} height={30} /> </button> )) }
同时,把Button组件中固定图标的require写法也改成根路径:
<Image className={styles.button_logo} src="/button_logo.svg" alt="IS_logo" width={50} height={50} priority />
2. 其他图片展示方式
如果不需要Next.js Image组件的自动优化(懒加载、格式转换、响应式缩放等),可以选择以下两种方案:
方式1:原生<img>标签
适合简单静态图标展示,无需依赖Next.js Image组件的特性:
<img src={button.icon} alt={button.label} width={30} height={30} className={styles.button_logo} />
方式2:SVG组件导入
若图标为SVG格式,可直接作为React组件导入,支持通过CSS自定义样式(如修改颜色):
步骤1:配置SVGR(Next.js默认支持,无需额外安装)
在next.config.js中添加SVG组件解析规则:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack(config) { config.module.rules.push({ test: /\.svg$/i, issuer: /\.[jt]sx?$/, use: ['@svgr/webpack'], }); return config; }, }; module.exports = nextConfig;
步骤2:导入并使用SVG组件
// 在Home组件中导入SVG图标 import ZavodIcon from '../public/icons/zavod.svg'; import GazpromIcon from '../public/icons/gazprom.svg'; import YaIcon from '../public/icons/ya.svg'; // 修改数组为组件引用 const compButtonsArray = [ { Icon: ZavodIcon, label: 'Label 1', transitionDelay: '0s', countBtn: "discord-button" }, { Icon: GazpromIcon, label: 'Label 2', transitionDelay: '0.1s', countBtn: 'twitter-button' }, { Icon: YaIcon, label: 'Label 2', transitionDelay: '0.2s', countBtn: 'reddit-button' }, ]; // 在Button组件中渲染 { companyButtons.map((button, index) => ( <button key={index} className={clsx(styles[`${button.countBtn}`], styles.button)} style={{ transitionDelay: `${button.transitionDelay}, ${button.transitionDelay}, ${button.transitionDelay}`, transitionProperty: 'translate, background, box-shadow' }} > <button.Icon width={30} height={30} /> </button> )) }
内容的提问来源于stack exchange,提问作者ivaivie
相关产品推荐
相关产品推荐

