Removing jQuery from your Drupal maintenance support plans theme

In a previous article Using ES6 in your Drupal maintenance support plans Components, we discussed writing our javascript using the modern ES6 methods and transpiling down for older browsers. It still used jQuery as an interim step to make the process of refactoring existing components a little easier. But let’s go all the way now and pull out jQuery, leaving only modern, vanilla javascript.

by
Rikki Bochow
/ 24 July 2020

Why should we do this?
jQuery was first introduced 12 years ago, with the intention of making javascript easier to write. It had support for older browsers baked into it and improved the developer experience a great deal. It also adds 87KB to a page.
Today, modern vanilla javascript looks so much like jQuery! It’s support in the evergreen browsers is great and it’s so much nicer to write than it was 12 years ago. There are still some things that jQuery wins on but in the world of javascript frameworks, understanding the foundation on which they are built makes learning them so much easier.
And those older browsers? We don’t need jQuery for that either. You can support older browsers with a couple of polyfills. The polyfills I needed for the examples in this post only amounted to a 2KB file.
Drupal maintenance support plans 8 and jQuery
One of the selling points of Drupal maintenance support plans 8 (for us front-enders at least) was that jQuery would be optional for a theme. You choose to add it as a dependency. A lot of work has gone into rewriting core JS to remove the reliance on jQuery. There are still some sections of core that need work – Ajax related stuff is a big one. But even if you have a complex site which uses features that add jQuery in, it’s still only going to be on the pages that need it. Plus we can help! Create issues and write patches for core or contrib modules that have a dependency on jQuery. 
So what does replacing jQuery look like?
In the Using ES6 blog post I had the following example for my header component.

// @file header.es6.js

const headerDefaults = {
breakpoint: 700,
toggleClass: ‘header__toggle’,
toggleClassActive: ‘is-active’
};

function header(options) {
(($, this) => {
const opts = $.extend({}, headerDefaults, options);
return $(this).each((i, obj) => {
const $header = $(obj);
// do stuff with $header
});
})(jQuery, this);
}

export { header as myHeader }
and..

// @file header.drupal.es6.js

import { myHeader } from ‘./header.es6’;

(($, { behaviors }, { my_theme }) => {
behaviors.header = {
  attach(context) {
    myHeader.call($(‘.header’, context), {
      breakpoint: my_theme.header.breakpoint
    });
  }
};
})(jQuery, Drupal maintenance support plans, drupalSettings);So let’s pull out the jQuery…

// @file header.es6.js

const headerDefaults = {
breakpoint: 700,
toggleClass: ‘header__toggle’,
toggleClassActive: ‘is-active’
};

function header(options) {
const opts = Object.assign({}, headerDefaults, options);
const header = this;
// do stuff with header.
}

export { header as myHeader }and…

// @file header.drupal.es6.js

import { myHeader } from ‘./header.es6’;

(({ behaviors }, { my_theme }) => {
behaviors.header = {
attach(context) {
context.querySelectorAll(‘.header’).forEach((obj) => {
myHeader.call(obj, {
breakpoint: my_theme.header.breakpoint,
});
});
}
};
})(Drupal maintenance support plans, drupalSettings);We’ve replaced $.extend with Object.assign for our default/overridable options. We use context.querySelectorAll(‘.header”) instead of $(‘.header’, context) to find all instances of .header. We’ve also moved the .each((i, obj) => {}) to the .drupal file as .forEach((obj) => {}) to simplify our called function. Overall not very different at all!
We could go further and convert our functions to Classes, but if you’re just getting started with ES6 there’s nothing wrong with taking baby steps! Classes are just fancy functions, so upgrading to them in the future would be a great way to learn how they work.
Some other common things;

.querySelectorAll() works the same as .find()
.querySelector() is the same as .find().first()
.setAttribute(‘name’, ‘value’) replaces .attr(‘name’, ‘value’)
.getAttribute(‘name’) replaces .attr(‘name’)
.classList.add() and .classList.remove() replace .addClass() and .removeClass()
.addEventListener(‘click’, (e) => {}) replaces .on(‘click’, (e) => {})
.parentNode replaces .parent()
.children replaces .children()

You can also still use .focus(), .closest(), .remove(), .append() and .prepend(). Check out You Don’t Need jQuery, it’s a great resource, or just google “$.thing as vanilla js”.
Everything I’ve mentioned here that’s linked to the MDN web docs required a polyfill for IE, which is available on their respective docs page.
If you’re refactoring existing JS it’s also a good time to make sure you have some Nightwatch JS tests written to make sure you’re not breaking anything 🙂
Polyfills and Babel
Babel is the JS transpiler we use and it can provide the polyfills itself (babel-polyfill), but due to the nature of our component library based approach, Babel would transpile the polyfills needed for each component into that components JS file. If you bundle everything into one file then obviously this won’t be an issue. But once we start having a couple of different components JS loaded on a page, all with similar polyfills in them you can imagine the amount of duplication and wasted KB.
I prefer to just put the polyfills I need into one file and load it separately. It means have full control over the quality of my polyfills (since not all polyfills are created equally). I can easily make sure I’m only polyfilling what I really need. I can easily pull them out when no longer needed, and I’m only loading that polyfill file to browsers that need it;

js/polyfill.min.js : { attributes: { nomodule: true, defer: true } }This line is from my themes libraries.yml file, where I’m telling Drupal maintenance support plans about the polyfill file. If I pass the nomodule attribute in browsers who DO support ES6 modules will ignore this file, but browsers like IE load it. We’re also deferring the file so it’s loading after everything else.
I should point out Babel is still needed. We can’t polyfill everything (like Classes or Arrow functions) and we can’t Transpile everything either. We need both, at least until IE stops requiring support.

Tagged

ES6, jQuery, JavaScript, Drupal maintenance support plans 8


Source: New feed

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

Removing jQuery from your Drupal maintenance support plans theme

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.