Terser 混淆后为什么我的 HTML 内联脚本失效了?
我用 Terser 打包压缩 JS 时,发现页面里一段内联脚本不执行了,但外链 JS 没问题。是不是混淆把某些变量名改掉了?
这段内联脚本是用来初始化全局配置的,结构大概像这样:
<script>
window.__INITIAL_CONFIG__ = {
apiUrl: '/api',
debug: false
};
</script>
我试过在 Terser 配置里加 keep_fnames 和 reserved,但还是不行,控制台报 __INITIAL_CONFIG__ is undefined。这到底该怎么处理?
根本原因不是变量名被改那么简单的。Terser 压缩的时候,它分析你的内联脚本,发现
window.__INITIAL_CONFIG__这个属性赋值之后根本没人用(它看不到 HTML 里其他外链 JS 会读这个变量),直接给你整个优化掉了。所以后面代码读window.__INITIAL_CONFIG__当然是 undefined。你试的
keep_fnames和reserved完全是方向错了:-
keep_fnames是保留函数名的-
reserved是防止某些名称被用作变量名的这俩跟对象属性一点关系没有。
正确做法是用
mangle.properties配置来保留这个属性:常见的解决方案有两个:
第一种,在内联脚本里加注释,告诉 terser 跳过这段代码:
第二种,如果你用的是 webpack + terser-webpack-plugin,检查一下配置,确保 HTML 里的内联脚本不会被二次处理。很多情况下是 html-webpack-plugin 或者其他插件在注入代码时触发了 terser。
另外提醒一下,
reserved选项是用来保留函数名的,不是变量名。你需要的是keep_fnames: true或者在mangle.properties里配置。最直接的办法还是用第一种注释法,基本上一用一个准。如果你是用其他打包工具(比如 Vite、Rollup 之类的),原理也差不多——都是要在打包流程里把这部分代码“保护”起来。