Refactoring Stone-Aged jQuery Codebase

Refactoring Stone-Aged jQuery Codebase: Modular jQuery code like modern frontend frameworks

I am working on an outlook add-on, smart-template. One part of the codebase is using old JavaScript, an earlier version of jQuery library. Both fixing bugs and adding new features become challenging because of the large files. Additionally, back in the day, reusable components were not very popular. Nowadays, we are very familiar with modern frameworks and tools like React, and Angular, where the codebase is opinioned and structured. Also, we use tons of reusable components.

An infographic of templating factory

Just by using reusable components, we can,

  • Reduce file size
  • Debugging becomes super easy
  • Create a safeguard for adding new features

In this article, I will share my experience on refactoring that very old codes into modular ones. For this purpose, although there are few templating engines available nowadays like Handlebars.js, pug.js, etc, we will use the oldest one, $.tmpl method.

An Example of Legacy jQuery Code

Let’s consider, we are going to render a list of users, where each of the users has name, age and gender property. With jQuery it is pretty straightforward as follows,

<!DOCTYPE html>
<html>
  <head>
    <title>Plain jQuery</title>
    <script
      src="https://code.jquery.com/jquery-1.7.2.min.js"
      integrity="sha256-R7aNzoy2gFrVs+pNJ6+SokH04ppcEqJ0yFLkNGoFALQ="
      crossorigin="anonymous"
    ></script>
  </head>
  <body>
    <div id="user-container"></div>
    <script>
      const users = [
        {
          name: 'Bob',
          gender: 'Male',
          age: '50'
        },
        {
          name: 'Alice',
          gender: 'Female',
          age: '30'
        }
      ];

      users.map(({ name, gender, age }) => {
        $('#user-container').append(`
        <div
          id="myTemplate"
          style="
            border: 1px grey solid;
            display: flex;
            justify-content: space-around;
            width: 100%;
          "
        >
          <div>${name}</div>
          <div>${gender}</div>
          <div>${age}</div>
        </div>
      `);
      });
    </script>
  </body>
</html>Code language: HTML, XML (xml)

Here, we imported the jQuery on the top. Later, we are using a div with id of user-container to render all the users. In the script, we build a dom with all the necessary data and append it to the user-container id.

Now there are a few limitations with this approach. First one, if I need to render the users in a different page, I have to write the code over and over. That duplication will cause tons of issues in the future. For instance, to fix a bug or styling, we will have to change the codes in multiple places.

Instead, what we can do is, create a template for individual users. Every time, we need to render a user, we will render the template with the new data.

A Modular Approach

Now, we will use a different file structure,

modular jQuery

We will write out JavaScript in the index.js file. To render user information we will utilize the user-item-template.html file. It is a reusable template without data. When we render the list of users, this user-item-template.html will receive some user data and render as HTML.

Out index.html will use additional tmpl library along with the jQuery,

<!DOCTYPE html>
<html>
  <head>
    <title>Modular jQuery</title>
    <script
      src="https://code.jquery.com/jquery-1.7.2.min.js"
      integrity="sha256-R7aNzoy2gFrVs+pNJ6+SokH04ppcEqJ0yFLkNGoFALQ="
      crossorigin="anonymous"
    ></script>
    <script src="https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
  </head>
  <body>
    <div id="user-container"></div>
    <script src="index.js"></script>
  </body>
</html>
Code language: HTML, XML (xml)

Our template user-item-template.html will only have a skeleton and can be invoked multiple times with the data,

<div
  id="myTemplate"
  style="
    border: 1px grey solid;
    display: flex;
    justify-content: space-around;
    width: 100%;
  "
>
  <div>${name}</div>
  <div>${gender}</div>
  <div>${age}</div>
</div>Code language: HTML, XML (xml)

To render the template, from index.js, we will load the template, provide the user-data and append the compiled HTML to the user-container id.

const users = [
  {
    name: "Name",
    gender: "Gender",
    age: "Age"
  },
  {
    name: "Bob",
    gender: "Male",
    age: "50"
  },
  {
    name: "Alice",
    gender: "Female",
    age: "30"
  },
  {
    name: "John",
    gender: "Male",
    age: "45"
  }
];

$.get("user-item.template.html", (template) => {
  users.map(user => $.tmpl(template, user).appendTo("#user-container"));
})
  .fail(function (xhr, status, error) {
    console.error("Error loading template:", error);
  });Code language: JavaScript (javascript)

We will see a similar output as before,

output

Conclusion

After jQuery 1.3 there are lots of options available for templating, however, for the earlier versions of code, tmpl can be a first choice to modularize the code. Since jQuery was one of the most famous and useful JavaScript libraries, still in some cases, we can not avoid its usage for simplicity. Feel free to leave any comments for clarification, changes, or improvements. Also, you can contact iXora Solution expert teams for any consultation or coordination from here.

Add a Comment

Your email address will not be published. Required fields are marked *