Capistrano部署生产环境遇Uglifier错误,开启harmony模式仍未解决
我之前碰到过几乎一模一样的问题,当时也是在部署Rails项目时卡在这里,给你分享几个排查和解决的方向:
1. 先确认配置是否真的生效
首先要确保你修改的是生产环境的配置文件:config/environments/production.rb,而不是development或者test环境的文件。有时候不小心改错文件,部署时根本没用到新配置,自然会报错。
另外,检查项目根目录的config/application.rb里有没有覆盖这个设置的代码,比如如果那里也写了config.assets.js_compressor = :uglifier,会覆盖production.rb里的自定义配置。
2. 调整Uglifier的配置参数
虽然你已经加了harmony: true,但在uglifier 4.x版本中,有些ES6+特性需要配合指定ecma版本才能生效。试试把配置改成这样:
config.assets.js_compressor = Uglifier.new( harmony: true, ecma: 2017, mangle: false # 如果还是报错,可以临时关闭混淆,排查是不是混淆阶段出的问题 )
ecma版本可以根据你代码里用到的ES特性调整,比如用了ES2018的特性就设为2018。
3. 清理资产缓存再预编译
Rails的资产管道很容易留缓存,就算你改了配置,旧的预编译文件可能还在。先在本地模拟生产环境预编译,看看能不能复现问题:
# 清理旧的预编译资产 RAILS_ENV=production rake assets:clobber # 重新预编译 RAILS_ENV=production rake assets:precompile
如果本地预编译成功了,那问题可能出在Capistrano部署时的缓存清理步骤。检查你的Capistrano配置,确保开启了资产清理:
# 在deploy.rb里添加 set :assets_clean, true
4. 检查JS代码里的特殊语法
有时候报错不是因为const,而是代码里有Uglifier harmony模式还不支持的ES6+特性,比如动态import()、可选链?.或者私有类方法。你可以把报错的JS文件单独拿出来,用Uglifier手动测试:
# 在rails console里测试(生产环境) RAILS_ENV=production rails c uglifier = Uglifier.new(harmony: true, ecma: 2017) # 读取报错的JS文件内容 content = File.read('app/assets/javascripts/your-problem-file.js') # 尝试压缩 uglifier.compile(content)
这样能定位到具体是哪一行代码导致的错误,如果确实是Uglifier不支持的特性,可能需要先用Babel转译这些文件。
5. 确认Uglifier版本正确
运行bundle show uglifier确认版本是4.1.20,如果版本不对,执行bundle update uglifier重新安装指定版本。
内容的提问来源于stack exchange,提问作者Ashish Jambhulkar

