TIL: Using ActiveAdmin with importmap-rails
Some of you might be thinking: Why?
Well I believe having less dependencies in my Rails applications is a good thing. Especially if those dependencies are in a another language and requires an additional dependency install. And since we are using Ruby and Rails I would be thrilled to get rid of node and package.json
in my project.
The benefit here, is that we don’t need to compile anything and that most browsers just works out the box.
There are actually two ways to do this. Either by using importmaps or by using a CDN directly with config.register_javascript
. The latter is probably the easiest.
Using a CDN directly
This is the easiest and most straightforward way of doing it. It requires you to have config.use_webpacker = false
then use config.clear_javascripts!
to make sure we don’t load the default javascript for ActiveAdmin.
Combining the above we get a config/initializers/active_admin.rb
file with the following:
ActiveAdmin.setup do |config|
# your other config stuff goes here...
# clear any previous assets
config.clear_javascripts!
# We need jQuery and jQuery UI and jQuery-ujs which are dependencies
config.register_javascript "https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.js"
config.register_javascript "https://cdn.jsdelivr.net/npm/jquery-ujs@1.2.3/src/rails.min.js"
config.register_javascript "https://cdn.jsdelivr.net/npm/jquery-ui@1.13.2/dist/jquery-ui.min.js"
# The actual active admin javascript file
config.register_javascript "https://cdn.jsdelivr.net/npm/@activeadmin/activeadmin@2.13.1/app/assets/javascripts/active_admin/base.min.js"
end
Restart Puma and voila! 🚀
Using importmap-rails
This requires tweaking ActiveAdmin a little bit. But otherwise it is fairly straight forward.
We start with doing config.clear_javascripts!
in config/initializers/active_admin.rb
. Just like before but we also have to add the script
tags for importmaps to the ActiveAdmin layout.
This is done by creating a module and prepending it to ActiveAdmin::Views::Pages::Base
and overriding build_active_admin_head
and using super
to retain the orignal implementation. I just put it all in the initializer like so
ActiveAdmin.setup do |config|
# ... any previous configuration goes here
# clear previous asset for javascript to make the asset pipeline
# happy
config.clear_javascripts!
end
module ActiveAdmin
module Views
module Head
def build_active_admin_head
within super do
text_node javascript_importmap_tags("active_admin")
end
end
end
end
end
ActiveAdmin::Views::Pages::Base.send :prepend, ActiveAdmin::Views::Head
The in my config/importmap.rb
I have pinned the modules we need and using the same urls are before
# The entrypoint
pin "active_admin", preload: true
# ActiveAdmin and dependencies
pin "@activeadmin/activeadmin", to: "https://cdn.jsdelivr.net/npm/@activeadmin/activeadmin@2.13.1/app/assets/javascripts/active_admin/base.min.js"
pin "jquery", to: "https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.js"
pin "jquery-ui", to: "https://cdn.jsdelivr.net/npm/jquery-ui@1.13.2/dist/jquery-ui.min.js"
pin "jquery-ujs", to: "https://cdn.jsdelivr.net/npm/jquery-ujs@1.2.3/src/rails.min.js"
The entrypoint app/javascript/active_admin.js
file just the modules needed for activeadmin
import 'jquery'
import 'jquery-ui'
import 'jquery-ujs'
import '@activeadmin/activeadmin'
Restart Puma and voila! 👏
Whats the better approach?
It depends. The CDN approach is way simpler than the importmaps
but it has some negatives. You have to always trust the CDN will never go down or the assets be removed.
The importmaps
method is more complex but can use local files. So the pinned assets can be downloaded into vendor/javascript
and that will ensure your assets are always present.