Users are encountering a Uglifier error during assets:precompile in Discourse 2.1.0, caused by ES6 const syntax in JavaScript files. The issue arises because the Uglifier gem, which bundles uglify-js, doesn’t support ES6 by default. Some users resolved it by enabling harmony mode or downgrading uglify-js to version 2.8. However, newer versions of Uglifier (4.2.0) now require terser instead of uglify-js, and the error persists if terser is not installed. The discussion highlights that terser should ideally be part of package.json, and users are finding workarounds to install it on Heroku. tmm1 notes that compress_ruby falls back to Uglifier only when terser is missing, and installing terser globally resolves the issue. pjdc confirms that the gem is only used if Node.js is unavailable or disabled, suggesting that the correct solution is to ensure Node.js and terser are properly set up.
I’m seeing some errors trying to run rake assets:precompile on 2.1.0 (stable branch), which appears to be due to the use of const in vendor/assets/javascripts/caret_position.js and app/assets/javascripts/service-worker.js.erb.
remote: 2018-09-11 02:38:12 +0000 Compressing: vendor-1d7e15932a900dc4b8be0306d85eb870358f859af13e8bd86e4b7fa9d859e1f1.js
remote: Compressing Javascript and Generating Source Maps
remote: rake aborted!
remote: Uglifier::Error: Unexpected token: keyword (const). To use ES6 syntax, harmony mode must be enabled with Uglifier.new(:harmony => true).
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/vendor/bundle/ruby/2.4.0/gems/uglifier-4.1.11/lib/uglifier.rb:234:in `parse_result'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/vendor/bundle/ruby/2.4.0/gems/uglifier-4.1.11/lib/uglifier.rb:216:in `run_uglifyjs'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/vendor/bundle/ruby/2.4.0/gems/uglifier-4.1.11/lib/uglifier.rb:178:in `compile_with_map'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:103:in `compress_ruby'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:150:in `compress'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:190:in `block (4 levels) in <top (required)>'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:160:in `block in concurrent?'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:183:in `block (3 levels) in <top (required)>'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:174:in `each'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:174:in `block (2 levels) in <top (required)>'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:160:in `concurrent?'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/lib/tasks/assets.rake:170:in `block in <top (required)>'
remote: /tmp/build_d4c490df87465281635b6b03a0274f93/vendor/bundle/ruby/2.4.0/gems/rake-12.3.1/exe/rake:27:in `<top (required)>'
remote: Tasks: TOP => assets:precompile
remote: (See full trace by running task with --trace)
It’s possible this something specific to my wacky environment (deploying to heroku), but I was able to resolve it using the fix suggested in the error:
Yeah, you are on quite a pain train here moving to DigitalOcean is my recommendation, our base image ships nodejs which rolls in features that are harmony as it goes
I ran into this myself recently on a different platform and solved it in a similar manner to OP.
Although uglify-js is itself a node module, the uglifier gem bundles the code itself and executes it directly with ExecJS.
However (see lib/tasks/assets.rake) the gem is only used if the node version is not available (or if it’s disabled).
So the version of uglifier specified in Gemfile.lock is simply incompatible with some of discourse’s JS, unless harmony mode is used. This is probably worth fixing or else removing entirely.
In any case, I now see that the expected situation is to install node and uglify-js so that Discourse uses that.