Webpack4同时启用terser与uglifyjs插件报错原因咨询
背景回顾
Webpack 4在生产模式或指定-p参数时,默认使用terser-webpack-plugin压缩JS包(-p是--optimize-minimize --define process.env.NODE_ENV="production"的快捷方式)。该大型应用未留意文档,在plugins数组中手动配置了uglifyjs-webpack-plugin,导致同时启用了默认的Terser和手动添加的UglifyJS双重压缩:
plugins: [ new CleanWebpackPlugin([TARGET_SERVER], { root: BASE_PATH + '/' + OUTPUT_PATH }), new UglifyJsPlugin(), ]
该配置正常运行3年后,突然出现ReactDOMServer.renderToString报错(错误提示为clearProviders is not a function),移除UglifyJsPlugin后问题解决。
报错核心原因
双重压缩导致代码损坏
Terser是UglifyJS的后继工具,两者压缩逻辑、语法支持范围存在差异:Terser完整支持ES6+语法,而旧版UglifyJS对ES6+特性处理不完善。当代码先经Terser压缩优化,再被UglifyJS二次处理时,UglifyJS会对已优化的代码再次进行混淆、"无用代码"剔除操作。ReactDOMServer内部的clearProviders方法可能被误判为未使用代码,或是二次混淆时破坏了函数的作用域、调用关系,最终导致运行时找不到该方法,抛出错误。依赖版本迭代触发隐藏问题
配置运行3年才暴露问题,本质是后续React或相关依赖包更新,引入了新的内部逻辑(比如新增clearProviders这类内部方法)。旧版UglifyJS对这些新增的ES6+语法或内部函数兼容性极差,双重压缩时触发了之前未暴露的代码损坏场景。而Terser作为Webpack 4默认压缩工具,对新版本React代码的兼容性更好,单独使用不会出现这类误处理。UglifyJS的维护缺陷
UglifyJS已停止维护,对新的JS语法、现代框架内部特性支持不足。当项目依赖的React版本迭代后,其内部代码使用了UglifyJS无法正确解析的语法模式,二次压缩时直接破坏了代码结构,引发运行时错误。
内容的提问来源于stack exchange,提问作者Vikram

