Build web components out of an existing Angular app with Angular elements

Maybe you have built an awesome website or web-app and another team of your company builds an associated app for smartphones with a different web-framework and wants to reuse some of your existing components.

Building/Extracting your components as web components makes them reusable in each and every other web project.

The idea

For each component we want to extract as a web component we need a separate Angular app. From that app we can import everything we want to have in our web component from our original app: Modules, services, animations, styles. Import everything you want or even create a tailored composition only for the web component, no limitations!

Luckily Angular CLI comes in handy and provides us with everything we need to have multiple apps in our project.

In addition, for convenient building and publishing our web components to npm, we can use Lerna.

Project setup

Let’s assume you have your existing Angular app and it is awesome, of course. Great! Start by adding a new app into your project using Angular CLI which will house our first web component:

ng generate application myWebComponent --routing=false --skipInstall=true

Replace with the name of your choice. We set because a web component does not have routing and the prevents rerunning npm/yarn install.

Within your project Angular CLI now creates a new projects folder with a new app in it. It also sets everything up in so it is ready to use!

Don’t worry about your initial app: You can still use all your common commands like or as before. This is because Angular CLI has defined your base app as the default project in :

"defaultProject": "myAwesomeApp"

Cleanup and setup

Inside our newly generated folder remove the created favicon and environments folder. If you want to just extract an existing component you can delete all stuff. If you want to tailor something customized together, only for the web component, keep the app component and use it as your base component.

For convenience add a path-variable to the web component app’s that references our base app:

"compilerOptions": {
...
"paths": {
"@app": [
"src"
],
"@app/*": [
"src/*"
]
}
},

Don’t forget to update the environment import in main.ts:

import { environment } from '@app/environments/environment';

Additionally, if you want, rename the folder to something more descriptive like but don’t forget to update all occurrences within , too. Within you can also set , so every other new app will land there, too.

Creating web components with Angular elements

Add Angular elements to your project. By using Angular CLI’s command and providing a project it even adds the required polyfill only to the web component app and not our base app:

ng add @angular/elements --project=myWebComponent

When you add more web component apps dont forget to add the polyfill to them, too.

Thats it! Now you can import what you want from your base app in your web component app and bootstrap them with Angular elements as usual:

import { BrowserModule } from '@angular/platform-browser';
import { DoBootstrap, Injector, NgModule } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { SomeComponent } from '@app/src/some.component';
@NgModule({
declarations: [
SomeComponent,
],
imports: [
BrowserModule
],
providers: [],
entryComponents: [
SomeComponent,
],
})
export class AppModule implements DoBootstrap {
constructor(private injector: Injector) {
const webComponent = createCustomElement(SomeComponent, {injector});
customElements.define('my-web-component', webComponent);
}
ngDoBootstrap(): void {
}
}

If you want to add global styles, that are not part of any component, import them relative in your . You can import everything all together or be selective:

@import "../../../src/styles";

For assets you want to include edit and change the assets array for your Web Component app. You may remove the favicon that we deleted there.

Build

Build the web component from the root of your project with the app name, in this example or

Preview / watch

If you edit the web component app’s index.html and replace with your defined tag name in you can even use to see the web component in action and try it out. You may also delete the favicon from index.html.

Publish to npm

For publishing to npm add a and a to each web component app’s folder and copy them in your dist folder after build. You could do that, for example, within a npm post build script.

Build, version and publish multiple web components automatically with Lerna

If you have a lot of web components it may become unhandy to do and for each of them manually. Luckily there is a tool called Lerna that does that for us. This may be a topic for itself, there is an in-depth article you can read about it. But in a nutshell:

  • Install Lerna
  • Define as your packages within .
  • Within change your web component app’s to be within the web component app’s root folder.
  • Add a build script to each web component app’s package.json.
  • Add a prepublish script to each web component app’s package.json that builds the app and copies package.json, e.g. . Lerna will execute this for each app before publishing.
  • Now you can run and it will automatically build all web component apps, increase their version number in package.json, publish them to npm and create git tags.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store