GatsbyJS中实现img标签相对路径指向指定目录且绝对路径正常生效
问题原因
- Gatsby的页面级GraphQL查询仅支持页面/模板组件使用,普通自定义组件无法识别这类查询定义
useStaticQuery不支持传入动态变量,无法匹配动态的src参数StaticImage仅支持构建时可静态解析的硬编码src值,不支持运行时动态传入的路径
可行方案:预构建本地图片路径映射表
该方案在构建阶段提前把所有指定图片目录的路径和对应资源地址生成映射表,运行时组件直接查表匹配,无需在组件内处理GraphQL,性能好且适配你的需求。
步骤1:配置构建钩子生成映射表
修改项目根目录的gatsby-node.js,添加onPostBootstrap钩子逻辑:
const fs = require('fs') const path = require('path') exports.onPostBootstrap = async ({ graphql, reporter }) => { // 查询所有images目录下的文件资源 const queryResult = await graphql(` query { allFile(filter: {sourceInstanceName: {eq: "images"}}) { nodes { relativePath publicURL // 如果需要使用Gatsby的图片优化能力,替换上面的publicURL为下面的gatsbyImageData配置即可 // gatsbyImageData(width: 1200, formats: [AUTO, WEBP, AVIF], placeholder: BLURRED) } } } `) if (queryResult.errors) { reporter.panicOnBuild('图片资源查询失败', queryResult.errors) return } // 生成路径映射表JSON文件 const imageMap = Object.fromEntries( queryResult.data.allFile.nodes.map(node => [node.relativePath, node.publicURL]) ) fs.writeFileSync( path.resolve(__dirname, 'src/constants/image-map.json'), JSON.stringify(imageMap, null, 2) ) }
步骤2:修改自定义Img组件
import React from "react" import imageMap from "../constants/image-map.json" // 如果使用GatsbyImage优化,导入对应组件 // import { GatsbyImage } from "gatsby-plugin-image" const absUrlReg = /^https?:\/\//i const CustomImg = ({ src, ...props }) => { let finalSrc = src // 非http开头的路径走本地映射匹配 if (!absUrlReg.test(src)) { if (imageMap[src]) { finalSrc = imageMap[src] } else { console.warn(`Image "${src}" 未找到`) } } // 原生img标签返回 return <img src={finalSrc} {...props} /> // 如果使用GatsbyImage优化,替换上面的返回为: /* if (absUrlReg.test(src)) { return <img src={src} {...props} /> } return <GatsbyImage image={finalSrc} {...props} /> */ } export default React.memo(CustomImg, (prev, next) => prev.src === next.src)
注意事项
- 首次添加配置后需要重启
gatsby develop才会生成映射表 - 新增/删除images目录下的图片后,重新启动开发服务会自动更新映射表
内容的提问来源于stack exchange,提问作者Giuseppe
相关产品推荐
相关产品推荐

