jQuery to ES6 and what if you don’t need a JS framework…

Joe Thom
Joe Thom
Mar 11, 2019 · 6 min read

A few years ago if you needed to add some interactive feature or functionality to your website the chances are you’d reach out for the DOM-centric selector sexiness of jQuery. These days however with the rise of “the modern javascript framework” more and more developers are flocking to these tools, (and for good reason). But what if your site doesn’t require a state and a declarative UI… should we still be using jQuery or is there an alternative way, a better way, an ES6 way?

I want to state = { workInProgress: true } that this is very much a work in progress and more of a high level overview of our build process. It works for our specific needs as an agency but might not fit your own.

A precursor

The plan

  • Modularity
    We wanted to break down our JS file structure to replicate something more similar to our SASS setup, separating functions into separate files and using ES6 import to pull through only what we needed per project.
  • Structure
    To improve cross-project knowledge and the passing of projects between developers we wanted to encourage common structuring of functions, at least at the beginning of a project.
  • Adaptability
    Sometimes our builds are passed onto a client who in turn insert them into their own stack to add more data driven content. Due to this it was important that our JS could be “hooked” (buzzwords yes please) into and updated accordingly, regardless of the client’s stack.
  • Modern
    At Inktrap we also develop more data driven web applications where the use of a framework such as React or Vue.js is required and ES6 is heavily used. We wanted to make sure that building a static site would also utilise the same or similar methods and thought process as our more complex builds, even if it wasn’t using a framework.

The results

Within the globals.js we created two global objects, FUNCTIONS & INSTANCES which I’ll briefly go into now:

An object of, you guessed it – all the function handlers in the site which can be called from the front-end at any time to initialise interactivity on any DOM elements.

An object consisting of any initialised class instances (which we call “modules”) containing methods and callbacks that can be accessed by any other JS functions.

We then came up with a common structure for our function handlers, here's an example being used in dropdownsHandler.js:

As you can see within the function handler we are initialising a new instance of our dropdown module. To give you a quick idea of what this does here’s an example of the initialisation and public methods that module provides.

Now — the above might seem a little like overkill just to initialise a simple dropdown. However using this method will give us access to two important abilities when it comes to “hooking” (yes I know) our front-end system into other client environments.

Before I go into that though, here’s a quick view of our load.js file which deals with the overall initialisation of our function handlers on page load:

After using the initialisation method above we now have access to our global FUNCTIONS & INSTANCES objects from the window object and we can see what they contain in the console:

The above visualises those two important abilities I mentioned earlier — the first being we now have a list of our custom function handlers that can be called at any point using:
- this is particularly useful for initialising over dynamic content thats been rendered after page load.

And secondly we now also have a list of any instances that have been initialised, each with their own methods and callbacks available to use elsewhere within our JS, for example:

Both of these abilities were essential in making our front-end templates more adaptable to any client environment due to the fact they can now “hook” (last time I promise) into almost any aspect of our JS.

Our learnings

  • Back-porting
    With modularity comes improved maintainability. In other words, by splitting up all of our functions into defined files, whenever we added new functionality or fixed a bug, we could easily back-port it into all other projects using the same system without worrying too much about merge conflicts.
  • Improved cross-project knowledge
    If every function is built using the common initialisation structure it makes it easier to pass between developers as they already have an idea of what they’re looking for and working with.
  • Removing reliance and improving control
    By removing libraries such as bootstrap and jQuery we no longer relied on third party tools so heavily and had complete control over what our clients had access to and utilise from our front-end JS.
  • Fallbacks
    Because we do not use a javascript dependant view (essentially we are using the base stack of HTML, CSS, JS) if for some reason our JS doesn’t load the user will still receive some resemblance of our site with HTML and CSS. Essentially we add the JS as an additional interactive layer, initialised by our markup.

Final thoughts, feelings & emotions

As I mentioned also in the beginning of this article, this is very much a high level overview of our build process specifically looking at our transition from jQuery to ES6 and the benefits it’s had. There’s plenty more I would like to go into such as how we initialise our JS from markup in a consistent way, our SASS/BEM setup and even potentially open sourcing our boilerplate repo but in the interest of time I wanted to keep this article (relatively) concise.

I do however plan on continuing to report on our learnings as we meander through these ever changing times of JS.

If you’ve got any feedback we’d love to hear from you — please leave a comment here, or drop us a line on Twitter, we’re @InktrapDesign.


Thoughts, feelings and emotions from the Inktrap team