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已经停止维护,存在兼容隐患。
修复步骤
- 修改资源引用方式:不要使用硬编码的静态路径,通过显式模块导入的方式让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'); - 调整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,大于阈值的输出为独立文件。 - 补全TS类型声明:在
src/types.d.ts中添加svg模块的类型定义,避免TS导入时报错:declare module '*.svg' { const src: string; export default src; } - 清理冗余文件:删除src目录下重复的
index.ts文件,避免构建冲突。
内容的提问来源于stack exchange,提问作者lomse
相关产品推荐
相关产品推荐

