gulp 压缩后网站 JS 莫名崩溃: uglify-js 只支持 ES5 的静默损坏与修复
前言
一个很折磨人的症状: 站点源码没问题, 本地预览一切正常; 走完 gulp 压缩发布后, 页面上某个交互组件崩了 —— 点击没反应, 控制台报错还指向压缩成一行的产物代码, 根本没法读。
更诡异的是: 压缩过程没有任何报错, gulp 正常退出, 构建日志一片绿。
排查下来根因有两层, 都是”老压缩链”的经典坑。这篇记录完整的定位过程和改造方案。
一、两个主角的问题
gulp-uglify: 底层只支持 ES5
gulp-uglify 底层用的是 uglify-js, 而 uglify-js 只支持 ES5 语法。现在的浏览器代码全是 ES6+: const/let、箭头函数、模板字符串、解构、class……
它翻车有两种方式:
- 直接报错中止 (算幸运): 类似
Unexpected token: name (...), 至少你知道坏了 - 静默损坏 (更糟): 部分代码能”压过去”, 但产物行为错误 —— 作用域被改写错、依赖
Function.name的逻辑失效、某些语法降级后语义变化。页面上组件直接崩, 而构建日志没有任何异常
第二种最迷惑: 你不会怀疑压缩环节, 只会反复检查业务代码, 而”本地预览正常、线上崩”的现象会把人往缓存和部署方向带偏。
gulp-htmlmin: 遇到未转义尖括号就中止整个流
HTML 压缩用 gulp-htmlmin 时, 只要流过它的某个文件里有未转义的半角尖括号标签文本 (比如文章正文里手写了一个裸的 <div 而没有放进代码块), 它会直接抛错, 中止整个压缩管道 —— 后面排队的文件全部不处理。
表现往往是: 构建失败提示含糊, 或者部分文件没被压缩就发布了。
二、修复思路
三个目标:
- 换用完整支持 ES6+ 的压缩器 →
terser(uglify-js 的社区延续分支) 和html-minifier-terser - 单文件失败不影响其他文件 → 压缩失败时保留原文件、打日志、继续
- 失败必须有日志 → 哪个文件、什么原因, 一眼可查
实现方式是用 through2 自己写转换流, 把错误处理接管过来, 不依赖插件的默认行为。
三、改造后的 gulpfile 模板
1 | const gulp = require('gulp') |
依赖安装:
1 | npm install gulp through2 terser html-minifier-terser fancy-log --save-dev |
这个模板的关键设计: 压缩失败时 next(null, file) 把原文件原样放行。坏一个文件只损失这一个文件不压缩, 换来的是构建永远能走完、问题永远有日志可查。
四、防回归的三个习惯
1. 正文里别手写裸的标签文本
文章内容里想展示 HTML 标签时, 用反引号包起来或放进代码块, 否则半角尖括号会原样进入 HTML 产物, 喂给压缩器就是一颗雷。
2. 构建后做一次语法抽查
1 | # 遍历产物 JS, 语法有问题的文件会报 SyntaxError |
这一步能兜住”静默损坏”的漏网之鱼 —— 语法层面坏掉的文件根本过不了 node --check。
3. 上线前点一遍核心交互
压缩引起的运行时问题 (作用域、Function.name 这类) 工具查不全, 关键页面的核心交互手工过一遍是最保险的验收。
五、怎么排查”压缩后才坏”的问题
如果你现在正处于”本地正常、发布后崩”的状态, 按这个顺序定位:
- 对比验证: 把对应文件的未压缩版本直接替换线上产物, 问题消失 → 实锤是压缩环节
- 缩小范围: 对该文件单独跑压缩, 再上线验证, 把”哪一步压坏的”锁死在 JS 或 HTML
- 定位原因: 打开 sourcemap 或对比源码与产物的关键函数, 看是被改写坏了还是根本没压缩
- 统一修复: 按第三节的模板迁到 terser, 别在旧插件上打补丁
小结
uglify-js只支持 ES5 —— 压 ES6 代码要么报错、要么静默损坏, 后者更危险gulp-htmlmin遇到未转义尖括号会中止整个管道 —— 正文里的标签文本要放进代码块- 修复方向: terser + html-minifier-terser + through2, 单文件容错, 失败留日志
- 压缩环节必须有语法抽查和人工验收兜底, 构建日志一片绿不代表产物没问题
老压缩链的问题不是”会不会坏”, 而是”坏了你知不知道”。把错误处理从插件手里接过来, 是这次改造最值的一步。
参考链接:
- terser: https://github.com/terser/terser
- html-minifier-terser: https://github.com/terser/html-minifier-terser
- through2: https://github.com/rvagg/through2
💡 准备购买云服务器 / 域名来搭建或部署站点?
通过下面的链接下单,通常能领到新用户专属优惠,也能小额支持本站持续更新:
阿里云(返现) | 腾讯云 2核2G 99元/年 | 腾讯云 云产品特惠













