Organize and serve page specific javascript in Phoenix with Webpack

Problem

On normal MVC application like Phoenix, there’s hundred of pages, and the task of manage which javascript function run on which page is quite troublesome. For hundred of page, manual declare or import/export file seem to be hard and take a lot of time, here is the solution that I come up with which help me to do the task by setup a convention name and by that automate the task of managing the javascript file for each and every page.

HTML layout

This is how a normal layout file look like, have and app.js file at the end of the body. And this file will contain both javascript functions that run on all screen, and javascript functions that run on page-specific screen.

HTML Layout file

In Phoenix, each page come along with @view_module and @view_template, we will use those 2 variables to make a unique name for each page, then javascript can read that unique name to identify the functions need to run on each page. The unique_view_name function can be defined in LayoutView

Unique-view-name Definition

So for example when I go to root_path, which are in context Public, controller Page and action is index, my body html would be public_pageview_index

Javascript Structure

We got only one file app.js that gonna be used in the layout file.

Javascript structure

We got common folder, which contain all shared javascript functions that we can used in multiple place.

And per_pages folder, which store javascript that run on each page, the name of the file in here is the exactly name of unique_view_name that we defined above.

The index.ts in per_pages folder will help us to auto-find the correct functions needed to run on a specific page.

index.ts

and the import & run javascript will be automatically by matching file name in per_pages folder with the unique_view_page on each page.

Each file on per_pages folder must export default a function, so that it can be call

Sample of per_page function

And finally the app.js file

app.js

With this, on every page, the function handleDOMContentLoaded will run, which will do 2 things:

  • run the base_functions() this is basically the common functions that run on every page, like popover, tooltip, select2, datepicker, etc.
  • run script_per_page() we just defined above, run javascript based on the unique_view_name of each page

Conclusion

This solution will work not only in Phoenix, but also in Rails so similar frameworks. For Rails, we can use the controller_name and action_name to setup the unique-view-name and other setups are just the same. Hope this could help someone who got same problems as I got.

Like what you read? Give Hoang Nguyen a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.