Kajol Singh

Frontend Developer Software Developer || Fascinated by tech trends || Building usable systems that work on web and mobile.

Stencil

Stencil is a compiler for generating web components developed by the Ionic team. Web components in Stencil can be used as standalone components, as a part of a Stencil web application, and as part of Ionic progressive web applications.

Components in Stencil are written in TypeScript and then compiled into various versions of JavaScript. Various bundles produced by a compiler are meant to be used in different scenarios.

Stencil takes features such as

  • Virtual DOM
  • Async rendering (inspired by React Fiber)
  • Reactive data-binding
  • TypeScript
  • JSX
  • Static Site Generation (SSG)

Why Stencil?

Stencil is a developer-focused toolchain for building reusable, scalable component libraries, applications, and design systems. It provides a compiler that generates highly optimized Web Components and combines the best concepts of the most popular frameworks into a simple build-time tool.

What does stencil do?

Stencil helps developers and teams build and share custom components. Since Stencil generates standards-compliant Web Components, the components you build with Stencil will work with many popular frameworks right out of the box, and can even be used without a framework because they are just Web Components. Stencil also enables a number of key capabilities on top of Web Components, in particular, prerendering, and objects-as-properties (instead of just strings)

 

Setup stencil

Stencil requires a recent LTS version of NodeJS and npm. Make sure you’ve installed and/or updated Node before continuing.

npm init stencil

Stencil can be used to create standalone components or entire apps. After running init you will be provided with a prompt so that you can choose the type of project to start.

Pick a starter › - Use arrow-keys. Return to submit.
 
    ionic-pwa 	Everything you need to build fast, production ready PWAs
    app       	Minimal starter for building a Stencil app or website
  ❯ component 	Collection of web components that can be used anywhere

Updating Stencil

To get the latest version of @stencil/core you can run:

npm install @stencil/core@latest --save-exact

Creating button Component with Stencil

First, we will create a dentsu-button component. Create a folder inside src/components named dentsu-button. Create the tsx (TypeScript) and css files for the component. The folder structure should look like this:

Stencil components are created by adding a new file with a .tsx extension, such as dentsu-component.tsx, and placing them in the src/components directory. The .tsx extension is required since Stencil components are built using JSX and TypeScript.

Here is an example of what a Stencil component looks like:

stencil-button

import { Component, Prop, h } from '@stencil/core';
 
@Component({
  tag: 'stencil-button',
  styleUrl: 'stencil-button.css',
  shadow: true
})
export class StencilButton {
 
  @Prop() variant : string;
  @Prop() shape: 'square' | 'round' = 'square';
  @Prop() size: 'small' | 'default' | 'large' = 'default';
 
  render() {
    return (
      <button class={`btn ${this.variant} ${this.shape} ${this.size}`} >
        <slot />
      </button >
    );
  }
}

Let’s discuss the elements from the core API used in the above component:

 tag in the @Component decorator defines the element tag to use this component in HTML

 styleUrl points to the styles (file) of the component.

  @component: @Component decorator is used to declaring a new web component

  @Prop: @Prop is used to declare an exposed property/attribute

Once compiled, this component can be used in HTML just like any other tag.

Index file

<stencil-button variant="primary" >stencil button</stencil-button>

Deploy and Publish Stencil with another framework

  1. Basic HTML 
  2. REACT
  3. ANGULAR
  4. VUE

Basic HTML :

While integrating the stencil with basic Html need to follow a few steps :

  • run npm run build inside the stencil folder
  • now copy the build and paste the same in the HTML project as mentioned below :
  • now import the script as done in stencil inside the index.html file 
  • and use the stencil component as mentioned below : 

React js (using directory path locally)

  • npm run build in the stencil directory
  • copy the repository path from the stencil now paste the same in the react directory and do npm i (i.e npm i /Users/user-name/Desktop/research-stencil)
  • Inside the react directory goto → index.js file do the following changes 
const App = () => {
  return (
    <>
    <h1>React app with Stencil</h1>
    <dentsu-button varient="primary">Dentsu button</dentsu-button>
    <dentsu-alert status="success" text="this is important alert message!"></dentsu-alert>
    <dan-side-drawer title="main menu"></dan-side-drawer>
    </>
  );   } export default App; 

 React js (using npm )

stencil directory

  • create an account in npmjs.com
  • Verify it by email 
  • Update the package.json (version) if needed
  • now do npm run build 
  • npm login 
  • npm publish

after publishing, you can see your published package in the npmjs.com

now you can use the package inside react directory and do the changes mentioned above for the index.js file 

Angular js 

As we already created the package via npm or we can use the repository path locally also 

now follow the steps for implementing the same in the angular repository :

  •  go inside the appapp.module.ts file do the following changes 
import { NgModule , CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
bootstrap: [AppComponent],
schemas:[CUSTOM_ELEMENTS_SCHEMA]
  • go inside the src → main.ts file do the following changes 
import { defineCustomElements } from 'web-component-stencil';
defineCustomElements(window);
  •    now go to the appapp.component.ts file and use the component 

Vue js 

as we mentioned above about the npm package or locally stencil path we need to do the npm i in vue repository after that need to follow the steps :

  • move into the src → main.js file and do the required changes mentioned below : 
import {
  applyPolyfills,
  defineCustomElements as defineStencilWebComponent
} from 'web-component-stencil/dist/loader'
 
applyPolyfills().then(() => {
  defineStencilWebComponent(window);
});
  • now move to the src → APP.vue file use the stencil component that’s it 
Share