In my web application I am trying to use Opal to program Javascript.
ruby-3.1.2
opal-1.7.3
opal-jquery 0.4.6
I am using guard-rake
to automatically compile any changes made to my opal files. Following are the relevant code snippets:
Rakefile
require 'opal'
require 'opal-jquery'
namespace :opal do
desc "Compile Opal files"
task :compile do
Opal.append_path "app/assets/opal"
builder = Opal::Builder.new
builder.build('opal')
builder.build('opal-jquery')
builder.build("main")
File.binwrite "app/assets/js/opal-main.js", builder.to_s
end
end
Guardfile
group :server do
guard "puma", port: 2300 do
watch(%r{config/*})
watch(%r{lib/*})
watch(%r{app/*})
end
guard 'rake', :task => 'opal:compile' do
watch(%r{^app/assets/opal/.+\.rb})
end
end
When I start the server the rake task runs successfully and the compilation also succeeds. The server logs are shown below
15:31:07 - INFO - Using Guardfile at /.../myapp/Guardfile.
15:31:07 - INFO - Puma starting on port 2300 in development environment.
15:31:07 - INFO - Starting guard-rake opal:compile
[23559] Puma starting in cluster mode...
[23559] * Puma version: 6.2.2 (ruby 3.1.2-p20) ("Speaking of Now")
[23559] * Min threads: 5
[23559] * Max threads: 5
[23559] * Environment: development
[23559] * Master PID: 23559
[23559] * Workers: 2
[23559] * Restarts: (✔) hot (✖) phased
[23559] * Preloading application
15:31:08 - INFO - running opal:compile
15:31:08 - INFO - Guard is now watching at '/.../myapp'
[23559] * Listening on http://0.0.0.0:2300
[23559] Use Ctrl-C to stop
[23559] * Starting control server on http://127.0.0.1:9293
[23559] * Starting control server on http://[::1]:9293
[23559] - Worker 0 (PID: 23579) booted in 0.0s, phase: 0
[23559] - Worker 1 (PID: 23581) booted in 0.0s, phase: 0
Then when I make changes to any file under path app/assets/opal
appended to Opal, guard-rake
runs the task to recompile the Opal files under that path, but in the server logs I see following error
15:32:13 - ERROR - Guard::Rake failed to run rake task <opal:compile>, exception was:
> [#] FrozenError: can't modify frozen Array: ["/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/opal-1.7.3/opal", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/opal-1.7.3/stdlib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/opal-1.7.3/lib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/ast-2.4.2/lib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/ast-2.4.2/lib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/parser-3.2.2.1/lib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/opal-jquery-0.4.6/lib", "app/assets/opal"]
Full logs are shown below
15:32:13 - INFO - Restarting Puma...
[23559] - Gracefully shutting down workers...
15:32:13 - INFO - Puma restarted
15:32:13 - INFO - running opal:compile
15:32:13 - ERROR - Guard::Rake failed to run rake task <opal:compile>, exception was:
> [#] FrozenError: can't modify frozen Array: ["/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/opal-1.7.3/opal", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/opal-1.7.3/stdlib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/opal-1.7.3/lib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/ast-2.4.2/lib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/ast-2.4.2/lib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/parser-3.2.2.1/lib", "/home/jignesh/.rvm/gems/ruby-3.1.2@myapp/gems/opal-jquery-0.4.6/lib", "app/assets/opal"]
[23559] * Restarting...
[23559] Puma starting in cluster mode...
[23559] * Puma version: 6.2.2 (ruby 3.1.2-p20) ("Speaking of Now")
[23559] * Min threads: 5
[23559] * Max threads: 5
[23559] * Environment: development
[23559] * Master PID: 23559
[23559] * Workers: 2
[23559] * Restarts: (✔) hot (✖) phased
[23559] * Preloading application
[23559] * Inherited tcp://0.0.0.0:2300
[23559] Use Ctrl-C to stop
[23559] * Starting control server on http://127.0.0.1:9293
[23559] * Starting control server on http://[::1]:9293
[23559] - Worker 0 (PID: 23926) booted in 0.0s, phase: 0
[23559] - Worker 1 (PID: 23928) booted in 0.0s, phase: 0
Can anybody please help in figuring out what is the issue causing the rake task fail?
Is there any problem in how I have defined the rake task?
Note: I am novice to Opal so please bear with any mistakes which looks silly to the experts.
Thanks.
The reason for that is pretty simple.
You can't execute Opal.append_path "app/assets/opal"
after the compilation. Which may happen, if the task is executed multiple times, which appears to be a case. You need to move that line outside of the rake blocks.
Of another thing, I would recommend to use opal-browser
instead of opal-jquery
.