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
- Basic HTML
- REACT
- ANGULAR
- 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 app ? app.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 app ? app.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