Uglifier error during assets precompile

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:

diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake
index bdca7c30ed..847a8d07c2 100644
--- a/lib/tasks/assets.rake
+++ b/lib/tasks/assets.rake
@@ -95,6 +95,7 @@ def compress_ruby(from, to)
   data = File.read("#{assets_path}/#{from}")

   uglified, map = Uglifier.new(comments: :none,
+                               harmony: true,
                                source_map: {
                                  filename: File.basename(from),
                                  output_filename: File.basename(to)

Yeah, you are on quite a pain train here :slight_smile: moving to DigitalOcean is my recommendation, our base image ships nodejs which rolls in features that are harmony as it goes

My guess, your node version is old

Which version of uglify are you running?

npm -g list uglify-js

It should be lower than 3.0.

I had the same error while upgrading from 2.0.3 to 2.1.0. We use our own Docker images

Updating to nodejs10 (from node8) didn’t fix the problem, but pinning uglify-js to the lastest 2.8 version fixed it ! Thanks @michaeld

Could you please explain precisely what change you applied to pin the uglify-js version (in Gemfile.lock I guess)…? :blush:
Thanks!

It’s not a gem, it’s a node module.

Something along the lines of

npm install -g uglify-js@"<3"

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.

내 harmony: true 해킹이 더 이상 작동하지 않아, 무의미한 uglifier 오류만 발생하고 있습니다:

remote:        Compressing: vendor-e356674b67559130cbeca4530a0a5a00e71144f5e7556902f8a5efc8ac3f2282.js
remote:        rake aborted!
remote:        Uglifier::Error:
remote:        /tmp/build_519258be/vendor/bundle/ruby/2.7.0/gems/uglifier-4.2.0/lib/uglifier.rb:291:in `parse_result'
remote:        /tmp/build_519258be/vendor/bundle/ruby/2.7.0/gems/uglifier-4.2.0/lib/uglifier.rb:221:in `run_uglifyjs'
remote:        /tmp/build_519258be/vendor/bundle/ruby/2.7.0/gems/uglifier-4.2.0/lib/uglifier.rb:176:in `compile_with_map'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:135:in `compress_ruby'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:178:in `compress'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:388:in `block (6 levels) in <main>'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:199:in `log_task_duration'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:383:in `block (5 levels) in <main>'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:189:in `block in concurrent?'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:382:in `block (4 levels) in <main>'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:371:in `each'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:371:in `block (3 levels) in <main>'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:189:in `concurrent?'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:368:in `block (2 levels) in <main>'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:199:in `log_task_duration'
remote:        /tmp/build_519258be/lib/tasks/assets.rake:367:in `block in <main>'

@pjdc 님이 지적했듯이, compress_ruby는 which terser를 통해 node 버전이 감지되지 않을 때만 사용됩니다. 제 환경에서는 실제로 terser가 없습니다:

~ $ node -v
v16.13.1
~ $ which terser
~ $

이제 npm install -g terser를 실행해야 하는 것 같습니다. 이것은 package.json에 포함되어야 하지 않나요?

How to Install Global npm Packages on Heroku - simonewebdesign 에 소개된 방법을 사용하여 Heroku에 terser를 설치할 수 있었습니다.