Kristján Oddsson detailed at the Web Components SF meetup how GitHub uses Web Components and the patterns GitHub identified to foster readable, performant, and accessible front end components.

Oddsson started by illustrating how a a simple behavior would be implemented in vanilla JavaScript at GitHub:

on('click', 'js-hello-world-button', function (event) {
  const button = event.currentTarget;
  const container = button.closest('js-hello-world');

  const input = container.querySelector('js-hello-world-input');
  const output = container.querySelector('js-hello-world-output');

  output.textContent = `Hello, ${input.value}`
}

with the corresponding HTML on the page:

<div class="js-hello-world">
  <input class="js-hello-world-input" type="text">
  <button class="js-hello-world-button">
    Greet
  </button>

   
</div>

The previous code does not rely on any abstractions beyond the standard web APIs and as such may be among the most efficient way to write the required behavior (displaying a welcome message on a button click). However, Oddsson mentioned a few issues with the approach: a naming scheme is required, the DOM querying is explicit, classes are not scoped and could be overloaded unwillingly. This results in more work on the developer side.

Oddsson then explained that the team at GitHub has been converting behaviors like the previous one into progressively-enhanced custom elements. GitHub’s custom elements align as much as possible on built-in elements behavior. GitHub custom elements additionally do not use the shadow DOM.

Oddsson then uses the <auto-check> custom element — that automatically check the availability of a repository name while the user is typing, to illustrate the boilerplate involved in writing web components.

First, custom elements define an interface that includes four methods (connectedCallbackdisconnectedCallback adoptedCallbackattributeChangedCallback) corresponding to different stages of the lifecycle of the element. An observedAttributes method also specifies which attributes to notice change for. Additionally, a custom element typically would have methods to retrieve and set the attributes that constitute the interface it exposes to the component users.

Then custom elements must be added to the registry if they are not already there (window.customElements.define method). The DOM elements that are involved in the behavior must also be queried — this.querySelector('input') for instance retrieves the input child element where the user enters the repository name. Additionally, as GitHub uses TypeScript, the relevant types must be created:

declare global {
  interface Window {
    AutoCheckElement: typeof AutoCheckElement
  }
  interface HTMLElementTagNameMap {
    'auto-check': AutoCheckElement
  }
}

#javascript #github #web components #web development #development #architecture & design #news

Web Components at Github
1.20 GEEK