Creating a Google Lighthouse custom audit that checks DOM elements

 |  Lighthouse, Custom Audit

Lighthouse provides a rich set of built-in audits but can also be extended to run your own custom audits. This can be extremely useful if you have your own specific checks that you want to perform on your site, such as checking all links to external sites have the rel="noopener" attribute or contain a specific class to visually indicate an external link etc.

Lighthouse report summary

In this article, we’re going to write a custom audit to check for the well known web accessibility issue of adding a click handler to a non-interactive element and not ensuring it’s accessible for keyboard and screen reader users. My article on Accessible JavaScript Click Handlers covers this web accessibility issue in more detail.


JavaScript modules for our custom audit

There are 3 JavaScript modules we’ll need to create for our custom audit.

  1. Gatherer — Collects information about the page. There are many standard gathers built-in to Lighthouse, including the AnchorElements gatherer, but this doesn’t collect all the details we require so we’ll create our own.
  2. Audit — Converts the gatherer data into a score and in our case, returns details to display for each element that has failed.
  3. Config — Provides the configuration for Lighthouse to register and run our custom gatherer and audit.
Read more

Automating Google Lighthouse audits and uploading results to Azure

 |  Lighthouse, Docker, Azure

This article covers configuring Lighthouse CI to run against a website and uploading the results to a Lighthouse CI server Docker container running both locally and in Azure.

Lighthouse is a great tool for auditing your website on performance, web accessibility, PWA, SEO and more. By automating Lighthouse to run nightly or with each commit and by uploading the results to a Lighthouse CI server, you can track your scores over time, see trends and detect when recent changes have had a negative impact. Lighthouse showing performance timeline

Lighthouse report comparison summary
Read more

Get Code Metrics On Your JavaScript Project Using SonarQube

 |  JavaScript, Code Metrics, SonarQube

While working on a large project, it can be very useful to keep on eye on key metrics about your codebase to see how your project is growing and review indicators that could mean you’re building up maintenance issues / technical debt.

SonarQube by SonarSource is a static analysis tool that supports 27 languages including JavaScript, TypeScript, HTML & CSS and can detect a range of issues in your codebase including bugs, code smells and security issues as well as provide traditional code metrics like lines of code and cyclometric complexity.

SonarQube example of reports

SonarQube additionally supports React JSX and Vue.js Single File Components (that use JavaScript, TypeScript in Vue.js SFCs will hopefully be supported soon.

SonarQube has several tiers available including a Community Edition which is free. This article covers running the Community Edition up in a Docker container and analysing a project to see the range of information SonarQube can provide.

Read more

Creating A .NET 5 ASP.NET Core App Running In Docker On A Mac

 |  .NET 5, ASP.NET Core, Docker, Mac

This article covers creating a new .NET 5 ASP.NET Core website in Visual Studio 2019 for Mac and running this website from both Visual Studio and from a Docker image.

Before we start, the following prerequisites need to be installed:


Create a new project and solution

Create a new “Web Application” project. Screenshot of VS2019 new project dialog box

Read more

BEM Class Names Checker

 |  BEM, CSS

After recently seeing a few BEM class naming issues on a project I was working on, I looked for an online site that would check a CSS stylesheet for BEM naming issues. I couldn’t find one… and what with being on lockdown here in England and having a fair amount of free time on my hands, I thought I’d write one!

Introducing the BEM Class Names Checker — An online tool to check a CSS stylesheet for common BEM naming issues.

Screenshot of BEM Class Names Checker website
Read more

BEM Visually Explained

 |  BEM, CSS

BEM (Block, Element, Modifier) is a methodology for naming CSS styles in a modular and maintainable manner. If you’ve worked on large websites, I’m sure you’ll have come across indecipherable class names and felt the pain of changing a style in one place and that breaking the styling elsewhere on something that seemingly isn’t related. These are issues that BEM will help you to avoid.

In this article, we’re going to use the example of a product card to explain BEM.

Product card showing a toilet roll
Product card example

BEM relies solely on CSS class names to apply styles to HTML so there are no HTML tag or ID selectors. BEM class names can consist of 3 parts [block]__[element]--[modifier].

Structure of BEM class names
Example BEM class name
Read more

5 Common Web App Accessibility Issues And How To Fix Them

 |  Web Accessibility, HTML

Over the years, I’ve worked on many large web app projects with developers of varying levels of experience and often see the same web accessibility issues crop up. In this article, I detail the 5 most common web accessibility issues I’ve come across and offer solutions for them.

Are you making / have you made these mistakes in your projects?


1) Using An Input Without An Associated Label

Wrong - Using plain text next to the input

Username <input type="text" name="username">

The text “Username” is not associated with the <input> so when a screen reader announces the <input>, it won’t announce that it’s for entering a username. The <input> will be announced along the lines of “input, edit text” so a screen reader user would have no idea what this <input> is for or what to enter.

The text “Username” also won’t act as a click / touch target to set focus to the <input>.

Read more

Using TypeScript With Knockout

 |  TypeScript, Knockout

Knockout is a minimalist, mature and proven library for creating web applications. It isn’t as feature rich as some of the more modern libraries & frameworks but it does what it does well, primarily being binding HTML elements against a data model. Even in 2019, I believe Knockout has its place and is still used on some very large projects, including Microsoft’s Azure Portal.

As of v3.5.0 (released Feb 2019), Knockout has built-in TypeScript definitions. https://github.com/knockout/knockout/blob/master/build/types/knockout.d.ts

TypeScript provides a huge amount of benefits over JavaScript including type safety, improved IDE tooling and additional constructs like interfaces and enums. If you have an existing project that uses Knockout, you can move over to TypeScript now and start enjoying these benefits.

This article will start with covering using TypeScript and Knockout’s type definitions to create view models, components and bindings that are strongly typed. We’ll then cover creating a new project from scratch that uses webpack and Babel to transpile TypeScript down to JavaScript (ES5).

Read more

Gradually Migrating To Typescript

 |  TypeScript, Babel

This article covers how to start using TypeScript modules in an existing project alongside JavaScript modules. If you have a large project, it may not be feasible to move to TypeScript all in one go. Gradually migrating provides more flexibility and allows you to, for example, use TypeScript just for new code or “upgrade” modules when there are changes to existing code.

TypeScript provides some huge benefits like types support, better IDE tooling and additional constructs like interfaces and enums so why not start making use of these now.

Read more

Vuex Getter With Parameters In TypeScript

 |  Vuex, TypeScript

When using Vuex with TypeScript, you typically use the @Getter decorator from the binding helpers package vuex-class. This is a more declarative approach over using this.$store.getters.*.

Vuex @Getter example

@Getter('books', { namespace: 'library' })
books!: Book[];

The getter above retrieves all books from the Vuex module library but what if you wanted to retrieve just a single book by it’s ID?

Read more