需修改三处:①gulp-rev的manifest赋值为originalFile + '?v=' + file.revHash;②rev-path返回filename + ext禁用重命名;③gulp-rev-collector匹配逻辑改为split('?')[0]并正则支持?v=xxx,HTML引用须为裸路径如css/style.css。

直接改 gulp-rev 的 manifest 写入逻辑
默认 gulp-rev 会把 style.css 映射成 style-abc123.css,但你要的是 style.css?v=abc123。关键就在它生成 manifest 的那一行——不是改文件名,而是拼 query 参数。
打开 node_modules/gulp-rev/index.js,找到类似 manifest[originalFile] = revisionedFile; 的赋值语句(通常在 133–144 行之间,具体行号随版本浮动)。把它替换成:
manifest[originalFile] = originalFile + '?v=' + file.revHash;
这一步决定了最终写进 rev-manifest.json 的键值对长什么样,是整个方案的起点。
禁用 rev-path 对文件名的重命名
gulp-rev 内部依赖 rev-path 拼接带 hash 的新文件名。如果你不拦住它,哪怕 manifest 写对了,磁盘上还是会生成 style-abc123.css 这种文件,白忙活。
立即学习“前端免费学习笔记(深入)”;
定位到 node_modules/rev-path/index.js(注意:不是 gulp-rev/node_modules/rev-path,新版已扁平化),找到类似 return filename + '-' + hash + ext; 的返回语句(常在第 9 或 10 行),改成:
return filename + ext;
这样 .pipe(rev()) 阶段就只计算 hash、不改名,CSS 文件原样输出到 dist/css/,只靠 URL 参数区分版本。
gulp-rev-collector 要能识别 ?v=xxx 形式
manifest 里存的是 "style.css": "style.css?v=abc123",但默认 collector 只认 style-abc123.css 这种后缀匹配。它会在 HTML 里找 style.css,然后试图替换成 style-abc123.css,结果啥也没换上。
打开 node_modules/gulp-rev-collector/index.js,找判断“是否匹配原始文件名”的条件分支(常见于 31、40 或 173 行附近),把类似:
path.basename(json[key]).replace(new RegExp(opts.revSuffix), '') !== path.basename(key)
的逻辑,改成:
path.basename(json[key]).split('?')[0] !== path.basename(key)
同时,确保正则替换部分支持可选的 ?v=xxx 后缀,比如把 regexp: new RegExp(pattern, 'g') 改成:
regexp: new RegExp(pattern + '(\?v=\w{8,12})?', 'g')
否则 collector 会反复追加 ?v=xxx,导致 script.js?v=abc?v=def 这种错误。
HTML 中引用必须是相对路径且无多余参数
gulp-rev-collector 匹配时只看 basename(即文件名+扩展名),所以这些写法会失败:
-
<link href="css/style.css?t=123">→t=123干扰 basename 提取 -
<link href="/css/style.css">→ 绝对路径和 manifest 键不一致(manifest 里是css/style.css) -
<link href="./css/style.css">→ 开头的./会让path.basename返回空字符串
务必统一用 css/style.css、js/app.js 这类不含协议、不含首尾斜杠、不含其他 query 的裸路径。这是最容易被忽略、也最常导致“明明改了代码却没生效”的地方。


















