Exposing Angular Components as Custom Elements From a Custom Angular Library

Since Angular 6 "Angular Elements" and "Angular Library" creation are possible via the CLI.  This post covers how to create a library and share components from that library as "Angular/Custom Elements" so any third party application can consume them.

In the age of Microservices the frontend is catching up, the term Micro frontends has been getting more traction of late.  Discarding the hype, the real value is in framework agnostic Web Components, allowing applications to compose components.

A lot of the examples I found didn't cover combining Elements and Libraries.  Also, the elements examples only cover very simple components with no dependencies.  So I've included a service dependency that makes a HTTP call in the custom element exposed.

Why? Well this approach is not suited to all applications but it does offer some nice features:

  1. Code organisation
  2. Shareable library that can be hosted in public or private npm repo
  3. Custom elements that any application may consume
  4. Host application that can compose library components

I wanted an Angular library that I could publish and get all the npm goodness.  I also wanted to expose components from my library as elements.

The Set Up

Create the Application

ng new my-application
cd my-application

Create The Library

ng g library my-library

This library will contain the components that may be imported into the my-elements project and defined as Custom Elements.  Of course, you could have multiple libraries and pick and choose which components need to be exposed as Custom Elements.

Create the Elements Project

ng g application my-elements

This is where we will import and define the components we want to expose as custom elements.

To add elements support run:

ng add @angular/elements

The above commands will update the angular.json file to use document-register-element to create our custom elements.

ng new my-elements

Notes

I've modified the tsconfig.json to target es2015 which won't work for IE, but you can workaround this by updating the polyfills.ts file in the main application to include webcomponents.js.

npm install @webcomponents

src/polyfills.ts

`/*******************************************************

  • WebComponent JS required for native view encapsulation.
    */
    import '@webcomponents/webcomponentsjs/webcomponents-sd-ce.js';`

Wrap Up

As your app grows you may find this approach saves architectural headaches down the line.  This approach does add some overhead so if your app is likely to stay small(ish) this is not the way to go.  I always advocate keeping it simple and reviewing every couple of weeks.

see source here

Serve and Rejoice!