ai/autoprefixer-rails

TypeError: Cannot read property 'version' of undefined

cseelus opened this issue · 5 comments

Just wanted to try autoprefixer-rails (latest) on a MacBook Air M1 running Node v14.16.1 for a Rails 6.1.3.2/Ruby 3.0.1 project that could use some browser-prefixes in a pdf.css file and got the following error:

eval (eval at <anonymous> ((execjs):1:213), <anonymous>:1:10) 
(execjs):1:213 
(execjs):16:14 
(execjs):1:40 
Object.<anonymous> ((execjs):1:58) 
Module._compile (internal/modules/cjs/loader.js:1063:30) 
Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10) 
Module.load (internal/modules/cjs/loader.js:928:32) 
Function.Module._load (internal/modules/cjs/loader.js:769:14) 
Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) 
execjs (2.8.0) lib/execjs/external_runtime.rb:39:in `exec' 
execjs (2.8.0) lib/execjs/external_runtime.rb:21:in `eval' 
execjs (2.8.0) lib/execjs/runtime.rb:64:in `eval' 
autoprefixer-rails (10.2.4.0) lib/autoprefixer-rails/processor.rb:134:in `runtime' 
autoprefixer-rails (10.2.4.0) lib/autoprefixer-rails/processor.rb:35:in `process' 
autoprefixer-rails (10.2.4.0) lib/autoprefixer-rails/sprockets.rb:22:in `run' 
autoprefixer-rails (10.2.4.0) lib/autoprefixer-rails/sprockets.rb:16:in `call' 
sprockets (4.0.2) lib/sprockets/processor_utils.rb:84:in `call_processor' 
sprockets (4.0.2) lib/sprockets/processor_utils.rb:66:in `block in call_processors' 
sprockets (4.0.2) lib/sprockets/processor_utils.rb:65:in `reverse_each' 
sprockets (4.0.2) lib/sprockets/processor_utils.rb:65:in `call_processors' 
sprockets (4.0.2) lib/sprockets/loader.rb:182:in `load_from_unloaded' 
sprockets (4.0.2) lib/sprockets/loader.rb:59:in `block in load' 
sprockets (4.0.2) lib/sprockets/loader.rb:337:in `fetch_asset_from_dependency_cache' 
sprockets (4.0.2) lib/sprockets/loader.rb:43:in `load' 
sprockets (4.0.2) lib/sprockets/cached_environment.rb:44:in `load' 
sprockets (4.0.2) lib/sprockets/base.rb:81:in `find_asset' 
sprockets (4.0.2) lib/sprockets/base.rb:88:in `find_all_linked_assets' 
sprockets (4.0.2) lib/sprockets/manifest.rb:125:in `block (2 levels) in find' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb:24:in `block in execute' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `block in synchronize' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `synchronize' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `synchronize' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb:19:in `execute' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/promise.rb:563:in `block in realize' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:363:in `run_task' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:352:in `block (3 levels) in create_worker' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:335:in `loop' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:335:in `block (2 levels) in create_worker' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `catch' 
concurrent-ruby (1.1.8) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `block in create_worker' 

Apparently process of

ExecJS.runtime.eval("process.version")

is undefined.

Bundling execjs to version 2.7.0 fixes this problem, so there seem to be some breaking changes in the newly released (first release after almost five years) execjs version 2.8.0.

This is a long known problem (see #160), then master branch, now released version of execjs decided to undefine process global, which makes determine the node version running via execjs very challenging.

see rails/execjs@b0be19c

Sine execjs 2.7.0 served us very well for 5 years without any major problem, I'll release a patch to lock to 2.7 until we figure out a way to deal with this.

Thanks for reporting!

Sine execjs 2.7.0 served us very well for 5 years without any major problem

Well, actually it's partly broken on Ruby 3.0, hence why a 2.8.0 was released.

May I ask why the need to check the node version?

Ok, self answer:

version = ExecJS.runtime.eval("process.version")
major = version.match(/^v(\d+)/)[1].to_i
# supports 10, 12, 14+
unless [10, 12].include?(major) || major >= 14
raise "Autoprefixer doesn’t support Node #{version}. Update it."
end
end

It is to eagerly error out. IMHO, I feel like this pre-check could be removed, and then a message could be appended if an actual error happen?

Or maybe there's some kind of feature testing that could be done instead of a version check?

Indeed, we don't absolutely need that version check, I'll have to change this quite a bit to ensure we can provide a good enough error though.

It is quite common for execjs to locate a nodejs binary not expected by the user, eg #189. (especially on ubuntu), so simply suggesting the user to check their node version is likely insufficient.

I'll try to address this properly in a few days, meanwhile 10.2.5.0 was released to lock with execjs 2.7.0

Thanks

Version 10.2.5.1 is now released, which is compatible with execjs 2.8.1, sorry for the delay