You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack 5动态创建img标签加载SVG资源返回404如何解决

问题原因
  • 静态字符串路径不会被Webpack解析:代码中直接写死img.src = 'assets/doggo.svg'属于纯字符串赋值,Webpack构建时不会识别这个字符串为资源依赖,既不会把对应svg文件打包到输出目录,也不会把路径替换为构建后生成的真实资源访问地址,直接访问对应路径自然返回404。
  • 资源规则配置不符合预期:当前配置中svg文件匹配的是asset/inline类型,该模式会将svg文件转换为base64格式的data URI内联到JS代码中,根本不会生成独立的svg实体文件输出到assets目录。
  • 配置存在冗余瑕疵:svg匹配正则末尾多了多余的|符号,会错误匹配无后缀文件;src目录下存在两个同名index.ts文件,容易引发构建解析冲突;使用的awesome-typescript-loader已经停止维护,存在兼容隐患。
修复步骤
  1. 修改资源引用方式:不要使用硬编码的静态路径,通过显式模块导入的方式让Webpack识别并处理资源,两种写法均可:
    • 顶部导入方式:
    // 注意根据当前文件位置写对相对路径,若代码在src根目录的index.ts中,路径为./assets/doggo.svg
    import doggoSvg from './assets/doggo.svg';
    const img = document.createElement('img');
    img.src = doggoSvg;
    
    • 动态require方式:
    const img = document.createElement('img');
    img.src = require('./assets/doggo.svg');
    
  2. 调整Webpack资源规则:如果需要svg作为独立文件输出而非内联为base64,将svg从asset/inline规则中移出,调整后的规则参考如下:
    module: {
      rules: [
        // TS解析 替换已废弃的awesome-typescript-loader为ts-loader
        {
          test: /\.tsx?$/,
          use: 'ts-loader',
          exclude: /node_modules/,
          include: __dirname
        },
        // 图片+svg 统一走resource类型输出为独立文件
        {
          test: /\.(?:ico|gif|png|jpg|jpeg|svg)$/i,
          type: 'asset/resource',
          generator: {
            // 自定义输出资源的存放路径和文件名规则
            filename: 'assets/[contenthash][ext][query]'
          }
        },
        // 字体 走inline类型内联
        {
          test: /\.(woff(2)?|eot|ttf|otf)$/,
          type: 'asset/inline',
        },
      ],
    }
    

    如果需要同时支持svg内联和独立文件输出,可以使用asset类型,配置大小阈值自动判断:小于阈值的文件内联为base64,大于阈值的输出为独立文件。

  3. 补全TS类型声明:在src/types.d.ts中添加svg模块的类型定义,避免TS导入时报错:
    declare module '*.svg' {
      const src: string;
      export default src;
    }
    
  4. 清理冗余文件:删除src目录下重复的index.ts文件,避免构建冲突。

内容的提问来源于stack exchange,提问作者lomse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:39:17