Webpack构建后srcset带w descriptor的文件名异常变更求助
解决Webpack html-loader处理srcset w descriptor时的文件名拼接错误问题
问题根源
html-loader默认的srcset解析逻辑会误将318w这类w描述符当成文件名的一部分,导致构建时把.webp后缀和描述符拼接在一起,出现video-preview-318.webpw-318.webp这类异常文件名。而x描述符(如2x)的解析规则和w不同,因此没有这个问题。
解决方案
1. 自定义html-loader的属性解析规则(推荐)
在webpack配置文件中,针对html-loader调整srcset的解析逻辑,明确区分文件路径和w描述符:
module.exports = { module: { rules: [ { test: /\.html$/i, loader: 'html-loader', options: { attributes: { list: [ // 保留默认的资源解析规则 ...require('html-loader/dist').attributesList, // 修复img标签的srcset解析 { tag: 'img', attribute: 'srcset', type: 'srcset', filter: (value) => { // 拆分每个资源项,分离路径和描述符 return value.split(',').map(item => { const [url, descriptor] = item.trim().split(/\s+/); return `${url} ${descriptor}`; }).join(', '); }, query: { name: '[path][name].[ext]', // 正则匹配到描述符前的路径部分 regExp: /(.+?)(?:\s+\d+w)?/ } }, // 同步修复picture标签中source的srcset { tag: 'source', attribute: 'srcset', type: 'srcset', filter: (value) => { return value.split(',').map(item => { const [url, descriptor] = item.trim().split(/\s+/); return `${url} ${descriptor}`; }).join(', '); }, query: { name: '[path][name].[ext]', regExp: /(.+?)(?:\s+\d+w)?/ } } ] } } } ] } };
这个配置会单独解析每个srcset项的文件路径和w描述符,仅对路径部分进行资源重命名,避免描述符干扰文件名。
2. 禁用srcset的资源解析(适合需保留原文件名的场景)
如果不需要html-loader处理srcset里的资源,直接在配置中排除srcset的解析即可:
module.exports = { module: { rules: [ { test: /\.html$/i, loader: 'html-loader', options: { attributes: { // 只保留需要解析的属性,移除srcset list: [ 'img:src', 'link:href', 'script:src' // 按需添加其他需要解析的属性 ] } } } ] } };
这样构建后srcset中的文件名会完全和原HTML一致,不会被修改。
3. 临时妥协:调整文件名命名方式
如果不想修改配置,可以把w描述符整合到文件名中,比如将video-preview-318.webp改为video-preview-318w.webp,这样html-loader不会混淆后缀和描述符,文件名能正常处理。这只是临时 workaround,优先推荐用配置解决问题。
内容的提问来源于stack exchange,提问作者Oleksandr
相关产品推荐
相关产品推荐

