Next.js 14中如何从src下app外的子文件夹动态导入图片?
问题描述
应用目录结构如下:
my-app| |src| |app |... |portfolio| |project_1 |project_2 |project_...
此结构符合Next.js官方指南。
现有Project组件,接收project对象并返回包含图片的组件,代码如下:
import React from "react"; import Image from "next/image"; export default function Project({project}: { project: any }) { let defaultDescription = project.descriptions; let imagePath = project.path+"/preview/pic.png" return ( <Image src={imagePath} alt={defaultDescription.title} width={50} height={50} /> ); }
遇到的问题:直接使用路径字符串或静态import都无法导入图片,因为每个项目有独立路径但图片名称相同,需要实现构建时静态打包、客户端动态加载的效果,无需服务端处理。
解决方案
方法一:使用require.context批量预加载图片
利用Webpack的require.context特性,在构建时扫描所有项目下的目标图片,将它们打包进静态资源,之后就可以通过项目路径动态获取对应图片。
修改后的Project组件代码:
import React from "react"; import Image from "next/image"; // 创建Webpack上下文,递归扫描portfolio目录下所有preview/pic.png const projectImageContext = require.context( "../../portfolio", // 相对于当前组件的portfolio目录路径 true, // 开启递归查找子目录 /preview\/pic\.png$/ // 匹配图片的正则表达式 ); export default function Project({ project }: { project: { path: string; descriptions: { title: string }; } }) { const defaultDescription = project.descriptions; // 通过项目路径从上下文中获取对应图片资源 const imageSrc = projectImageContext(`./${project.path}/preview/pic.png`); return ( <Image src={imageSrc} alt={defaultDescription.title} width={50} height={50} /> ); }
原理:require.context会告诉Webpack在构建阶段遍历指定目录下的匹配文件,把所有符合条件的图片都打包到输出目录中,运行时可以通过相对路径直接获取已打包的资源URL。
方法二:将图片迁移到public目录
如果允许调整目录结构,可以把项目图片移到public/portfolio目录下,结构如下:
my-app| |public| |portfolio| |project_1| |preview| |pic.png |project_2| |preview| |pic.png
然后修改组件中的图片路径为绝对路径:
import React from "react"; import Image from "next/image"; export default function Project({ project }: { project: { path: string; descriptions: { title: string }; } }) { const defaultDescription = project.descriptions; const imagePath = `/portfolio/${project.path}/preview/pic.png`; return ( <Image src={imagePath} alt={defaultDescription.title} width={50} height={50} /> ); }
注意:如果部署到非根域名,需要在next.config.js中配置basePath;另外,next/image对public目录下的资源支持开箱即用,构建时会自动处理静态资源的复制和优化。
内容的提问来源于stack exchange,提问作者Rox
相关产品推荐
相关产品推荐

