January 23, 2022 Migrating to jsbundling-rails
Now that Webpacker is riding off into the sunset, many of us find ourselves switching over to using one of the solutions offered by jsbuilding-rails.
With the move comes a much simplier javascript story, which is a welcome change for many of us, but making the move can quickly lead to a few gotchas. Below I’ll outline the few that I’ve run into and how you can avoid them so you can ensure a smooth transition to using esbuild.
Gotcha #1 - Importing CSS in your Javascript
This has been one of the most common problems I’ve noticed folks having. Say you’re using a javascript
package that also includes CSS assets, esbuild does allow you to import those, but will name
the output file the same name as the root javascript file in app/javascript
which in most cases will be application.js
.
The result of that being two files output to app/assets/build
, application.js
and application.css
- and that’s where the hang-up occurs. If you are also using cssbundling-rails it will by default name it’s output the same thing - application.css
, causing a naming collision that will inevitably cause you to bang your head against the wall if you aren’t sure what’s going on.
There are two solutions here, one is renaming the output of your cssbundling-rails
file, or renaming your app/javascript/application.js
to something else, which in my case is what I did, making it application-esbuild.js
. Now, esbuild will process your javascript and CSS and place two files named application-esbuild.js
and application-esbuild.css
into app/assets/build
. Then all you need to do is make sure you include those files in the head of your application.html.erb
file:
<!-- app/views/layout/application.html.erb -->
<%= stylesheet_link_tag "application", media: :all, data: { turbo_track: "reload" } %>
<%= stylesheet_link_tag "application-esbuild", media: :all, data: { turbo_track: "reload" } %>
<%= javascript_include_tag "application-esbuild", data: { turbo_track: "reload" } %>
Gotcha #2 - Having Two Javascript Directories
If you’re not starting fresh in Rails 7 there’s good chance you’ve got files in app/assets/javascript
.
If so you’ll also want to make sure you’ve got sprockets setup to serve those assets. This can be done in app/assets/config/manifest.js
, just make sure you’ve got the following line in the config:
// app/assets/config/manifest.js
//= link_tree ../images
//= link_tree ../fonts
//= link_tree ../builds
// this is the key addition, referring to the file app/assets/javascript/application.js
//= link application.js
Of course you could also use link_tree
or any of the other methods that sprockets provides in order
to properly include the necessary javascript files in app/assets/javascript/
, but I think explicitly
including just one file helps keep things clean and easy to understand.
Also note that doing this also assumes that you’ve renamed your esbuild output file to application-esbuild.js
as mentioned above, otherwise you’d run into similar naming collision issues that Gotcha #1 covers.