In this post we are going to learn how to use a Stencil Web Component in a Angular CLI application. Stencil is a compiler that allows us to author reusable Web Components. To learn more check out how to get started with your first Stencil Component.

In our previous post we learned how to create our first Stencil Component, a simple drop down. Now we will take that same component and publish it to NPM to be able to use it in a Angular CLI project.

Publishing our Stencil Component

There are several ways to publish and distribute a Stencil Component. We could via a git repo, a script cdn or NPM. For this demo we will use NPM. The code for our Stencil dropdown can be found here.

To publish our Stencil Component we need to do the following steps. First we need to check our stencil.config.js. In here we set generateDistribution: true. This will set the compiler to generate the files needed for other projects to consume our Stencil components.

Once configured we will run the npm script npm run build this runs the build process to generate our components. Once built we can publish our components to NPM. To publish our components we run npm publish this will publish the generated components in the dist folder to our project name defined in our package.json file. The demo project I have already published to NPM here. Next we will look at a Angular CLI project to consume our components.

Configuring the Angular CLI

Now we have our Stencil Components published to NPM we can add them to our Angular project. In this demo we are going use the Angular CLI. First we need to install the demo package to our CLI project. To do this we will run npm install stencil-demos.

Once installed we have to make some changes to the .angular-cli.json file. Unfortunately at the time fo writing Stencil does not yet support ES2015 module importing of individual components which means we must configure the CLI to copy all the static JavaScript files to use at runtime. Hopefully in new versions this will be more configurable to allow importing direct ES2015 modules as well.

In the .angular-cli.json we need to add a configuration object to the assets settings.



"assets": [
  "assets",
  "favicon.ico",
  { "glob": "**/*", "input": "../node_modules/stencil-demos/dist", "output": "./assets/stencil-demos" }
],


Our configuration object defines how the CLI should copy the JS files from our NPM package over to our assets directory to be available at runtime. Once set we need to add the following to our index.html file.



<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularStencilWebComponentDemo</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <script src='assets/stencil-demos/index.js'></script>
</head>
<body>
  <app-root></app-root>
</body>
</html>


We add a script tag to link to the core code that will use the Stencil component loader. The component loader allows all the stencil components to be lazy loaded only when rendered on the screen giving some nice default performance benefits.

Now that we have everything wired up we need to let the Angular compiler know that we are using Web Components. To do this in our app.module.ts file we need to add the following.



import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [
    CUSTOM_ELEMENTS_SCHEMA // Tells Angular we will have custom tags in our templates
  ]
})
export class AppModule { }



The CUSTOM_ELEMENTS_SCHEMA tells the Angular compiler that any unknown tags should be ignored as they will be defined by our custom Web Components. Once defined we can now add our Stencil component in our app.component.html template.



<h1>Stencil Web Components and Angular</h1>
<my-dropdown title="Toggle">
  Hello from a Web Component build with Stencil in a Angular App!
</my-dropdown>


If we start up our Angular app using ng serve we will see the following:

Stencil is a great way to write generic web components that can be reused anywhere including Angular. Check out the full demo below!

Demo