NextJS如何动态导入未存放在public文件夹下的图片资源?
解决方案
原写法失效原因
你的动态import()写法存在两个核心问题:
- 动态
import()返回的是Promise对象,而非直接的资源路径,需要等待异步返回才能拿到正确值 - 存放在项目根目录的
textbooks文件夹默认不属于Next.js的模块处理范围,webpack不会对该目录下的静态资源做导入解析
可行方案
方案1:构建时自动同步图片到public目录(推荐)
不用手动移动文件,通过webpack插件在构建阶段自动把教材目录下的图片同步到public目录,实现零手动操作:
- 安装依赖
npm install copy-webpack-plugin --save-dev
- 修改
next.config.js配置
/** @type {import('next').NextConfig} */ const CopyPlugin = require("copy-webpack-plugin"); const path = require("path"); const nextConfig = { webpack: (config) => { config.plugins.push( new CopyPlugin({ patterns: [ { from: path.resolve(__dirname, "textbooks"), to: path.resolve(__dirname, "public/textbooks"), // 仅同步图片文件,避免复制markdown等非必要资源 filter: (resourcePath) => /\.(png|jpe?g|gif|svg|webp)$/i.test(resourcePath), }, ], }) ); return config; }, }; module.exports = nextConfig;
- 图片引用方式调整为:
<NextImage src={`/textbooks/textbook-1/images/${imgFile}`} alt="教材配图" width={xxx} height={xxx} />
方案2:服务端读取图片转Base64
如果不想往public目录写入文件,可以在服务端渲染/静态生成阶段直接读取图片文件转成Base64地址传递给组件:
// 服务端执行的逻辑,比如getStaticProps或App Router服务端组件内 import fs from 'fs/promises' import path from 'path' async function getTextbookImageSrc(textbookId, imgFileName) { const imgFullPath = path.join(process.cwd(), 'textbooks', textbookId, 'images', imgFileName) const imgBuffer = await fs.readFile(imgFullPath) const extName = path.extname(imgFileName).slice(1) return `data:image/${extName};base64,${imgBuffer.toString('base64')}` }
该方案更适合单张图片体积较小的场景,大体积图片转Base64会显著增加页面体积。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

