Forem has created a milestone to migrate Javascript initializers in asset pipeline to pack tags and we need YOUR help!
In an effort to migrate away from asset pipeline and to more modern JS management, there are various initializers that need to be migrated to pack tags via Webpacker and initialized in the perspective view/page. If youβre looking to contribute to open source, these are great issues (tagged with ready for dev
in the milestone) to work on π This post will help guide you through them.
A Little Background
Using Webpacker in Rails provides several advantages over the traditional asset pipeline. First, Webpacker uses JavaScript modules, which allows for better code organization and improved code reusability. Second, it offers modern frontend build tools, such as Babel and PostCSS, for transforming and compiling assets. Third, it provides faster build times and faster runtime performance through code splitting and lazy loading. Fourth, it offers better integration with JavaScript frameworks such as React, Vue, and Angular. Overall, Webpacker offers a more flexible and modern asset management solution for Rails applications. And while Webpacker is being retired, this initiative is to consolidate our code accordingly before moving our bundler to another solution.
High-Level Summary
As Webpacker is already a current dependency in the application, we can begin by migrating an initializer file from app/assets/javascript
to app/javascript
. We will then change the references to your JavaScript files in your views and layouts to use pack tags instead of the traditional asset pipeline tags.
These steps are a high-level summary and may require additional steps or modifications based on your specific requirements and initializer purpose. It's always recommended to thoroughly test any changes to the application before submitting a Pull Request.
See Forem Dev Docs for further Webpacker references
Step-by-Step with an Example
In setting out to migrate the initializeCommentDate
function(app/assets/javascripts/initializers/initializeCommentDate
), we first create the file under
and begin moving the code to the newly created file. While some of the code in asset pipeline makes use of CommonJS standards, Javascript under pack tags makes use of ES6 standards. There may be occasions in which those standards would need to be met (i.e. using
app/javascript/packs/initializers/let/const
over var
, etc.). These corrections/updates can be captured and identified through our linting commands.
import { addLocalizedDateTimeToElementsTitles } from "../../utilities/localDateTime";
export function initializeCommentDate() {
const commentsDates = document
.querySelectorAll('.comment-date time');
if (commentsDates) {
addLocalizedDateTimeToElementsTitles(commentsDates, 'datetime');
}
}
You would also want to migrate any dependencies in which the initializer makes use of. In this case, we migrated addLocalizedDateTimeToElementsTitles
from localDateTime
as a utility function as well.
Next, and one of the most important steps, is determining where to place the reference to the pack tag. Most initializers are global initializers (i.e. initializeBaseTracking
) meaning they are required throughout the application, thus, we place those tags in the application.html.erb
file as such:
<%= javascript_packs_with_chunks_tag "base",
"baseInitializers",
"Search",
"runtimeBanner",
"onboardingRedirectCheck",
"contentDisplayPolicy", defer: true %>
But there may be initializers that may only get initialized on Article pages, etc. It would be a good idea to determine what view the initializers are initialized for and add the pack tag reference to that specified view.
A great, simplistic way of testing locally whether your new pack initializer is being triggered is by logging to the console the initial call and any known or derived variables from the code. In my case, I log commentsDate
and assure the localDateTime
is added to a title attribute (See addLocalizedDateTimeToElementsTitles
). Those are good signs that the initializer is being initialized!
Lastly, remove the asset pipeline references to the initializer and delete the file under app/assets/javascripts/initializers
and that's all there is to this great long-awaited migration!
You can find the code for this example here.
If you have any questions or feedback, please drop them in the comments below. If youβd like to contribute to this great migration please have a look through the ones that arenβt assigned in this milestone and raise your hand on the issue. We look forward to your contributions!
Top comments (1)
You'd probably need an exhaustive audit. I remember some PRs with nasty surprises, which is not uncommon for such open-source platforms with "LTS."
This is huge work @lboogie2004 unless you find some cheat codes. Also, InstantClick can raise issues github.com/forem/forem/issues/18943.