Stencil components in React, Vue, and Angular
[UPDATE: Aug 7, 2018 — Simpler and better intructions]
[UPDATE: Nov 8, 2018 — Update instructions for Stencil ≥ 0.13.x]
Stencil is not a framework. Stencil provides an elegant API that lets developers write components in TypeScript, and then takes care to compile them into completely standard web components (Custom Elements v1) that can be consumed by any framework.
I first heard about Stencil at a talk from Ionic’s Mike Hartington back in January, and thought it was an appealing idea. Unfortunately I didn’t have the time to dive into it back then, but last week I finally set off to write my first Stencil component. The documentation is very good, and I was able to have my first component ready in no time. The trouble started when I tried to include the component in an existing React project. Due to my lack of experience, this simple operation turned into a few very frustrating hours. The documentation provided by Stencil almost gets you there, but I found that it could be more detailed especially for people like me that may find some of the steps not obvious.
I believe Stencil’s technology is great, and I want to help lowering the entry barrier for others by sharing a few things I had to figure out on my own when trying to use Stencil components in React, Vue, and Angular applications.
To keep it short, I will only go over the React example here, but I am including links to equivalent step by step examples I wrote for Vue and Angular on Github.
0: Build a stenciljs component and publish it to npm
Creating your first stencil component is very easy and it is well documented here.
This example will consume two components:
- @openchemistry/molecule-vtkjs : To display molecular structures
- split-me : To create resizable split layouts
1: Add the component(s) to the app dependencies
Add the component to the app dependencies in package.json
2: Load the component(s)
Import the component in the index.js
of the app:
3: Consume the component
It is now possible to use the tag provided by the stencil components in the render
function of any react component.
Appendix: Attribute vs Prop
oc-molecule-vtkjs
has a property named cjson
that expects a complex object.
Strings and numbers can be passed directly as attributes to a stencil component.
One way to pass a complex object to a component could be to JSON.stringify()
the object and thenJSON.parse()
it inside the component. But this round trip can be expensive, and it would be a good idea to pass the object directly as a prop.
React doesn’t provide a convenient way to distinguish between attributes and props, so a little work is needed to achieve this.
In the end, it just boils down to saving a reference to the element of the stencil component, and then set the property directly in the javascript code.
To make this operation easier, it can be convenient to create a reusable utility function wc
.
And then use it in the jsx
to bind events and properties to the webcomponent this way:
Conclusion
Writing reusable web component with Stencil is easy. The same Stencil component will be able to run inside a React, a Vue, an Angular app, or whichever framework will come out next month.