Run, Build & Deploy Stencil and Storybook From One Repository
I recently joined a project where the team used two separate Git repositories for their web components based on Stencil and Storybook. But the idea of Storybook is that the so-called "stories" live next to the components source code. Therefore, it made no sense to me to have those two tools in different repositories, and I combined them both in one repository.
My goal was that developers can also use Storybook stories via hot reload during development. Additionally, it should still be possible to separately deploy the web components to a npm registry and Storybook to a public URL.
This article describes the necessary steps to combine Storybook and Stencil in one repository. I wrote this article as there is currently no official documentation available on how to use Storybook with Stencil. Let's start with some basics.
Stencil
Stencil is a toolchain for building reusable, scalable Design Systems. Generate small, blazing fast, and 100% standards based Web Components that run in every browser.
Stencil combines the "best concepts of the most popular frameworks into a simple build-time tool" that provides features like:
- TypeScript support
- JSX support
- One way data-binding
As you can see from these picked concepts, Stencil is a React-inspired web component library. I previously worked with lit-element but due to the above-mentioned features, I prefer working with Stencil, especially in React projects.
Init Stencil
Let's create a new Stencil project which will be the base for the demo project of this article which is available at GitHub:
We choose the component
starter as we want to build a web component library that can be shared via npm:
Now we modify the automatically created my-component.tsx
to be a bit more complex:
Our demo component is a native HTML select component that gets its options passed via property. Some values like the label text, the component name, and if the component is disabled are also passed via props to the web component.
Run Stencil web components
To be able to locally test our demo component we need to adjust src/index.html
which is used if we start Stencil:
Now we can locally test our demo component by running npm run start-stencil
which is an auto-generated npm script from Stencil. The component should now be visible at http://localhost:3333
:
Build & deploy to npm registry
The next step is to deploy our component to an npm registry. For this demo, I use Verdaccio which is a "lightweight open source private npm proxy registry". First, it needs to be installed globally
and then it can be started locally:
Now we have a local npm registry available at http://localhost:4873/
so we need to tell npm to use that registry, for example, by modifying .npmrc
:
Additionally, we need to create a user in our registry:
Finally, we can pack the package and publish it to the npm registry:
It should now be visible in our private registry at http://localhost:4873/
:
At this point, we have a working Stencil web component library that can be deployed to any npm registry. The next step is to integrate Storybook into our repository.
Storybook
Storybook is an open source tool for developing UI components in isolation for React, Vue, Angular, and more
A typical use case for Storybook is to have a visual representation of a web component library. This allows any developer or designer to see which components are currently available and how they look and behave.
Init Storybook
As Stencil components are compiled to web components we can use the Storybook for HTML project type:
Run & build Storybook
If we now run npm run storybook
it opens a browser window at http://localhost:6006
which shows some automatically generated components & stories:
Now let's write a story for our <my-component>
demo web component:
In our story, we defined Controls to be able to manipulate our component properties inside Storybook. We also added some default values and descriptions.
But unfortunately, we cannot see our component inside Storybook and need to do some further adjustments to the project setup.
First, we need to load and register our web components in .storybook/preview.js
to include them in webpack's dependency graph. This JavaScript code is added to the preview canvas of every Storybook story and is therefore available for the webpack build:
Now we need to add @storybook/react to be able to use our component in the story:
Next step is to modify our my-component.stories.js
:
Finally, we need to add two new npm scripts:
By running Stencil's build process with the --watch
flag it generates the correct output with the esm/loader.mjs
file we reference in the preview.js
file. We then just need to tell Storybook to use the dist
folder generated by the Stencil build command and disable its caching mechanism.
If we now run build-stencil:watch
and then start-storybook
in a separate terminal we can see our component in Storybook:
You can now also modify your Stencil web component and due to the hot reload you can see immediately your changes in Storybook.
You might also wonder how we can set options via property? It is possible by using setTimeout
inside the Template function in my-component.stories.js
to ensure that the component has been loaded:
Deploy Storybook
Finally, we want to deploy Storybook to a public URL and therefore we use storybook-deployer which provides a nice way to deploy it to GitHub Pages or AWS S3. We will deploy it to AWS S3 by installing the tool
and adding some new scripts to package.json
:
Before we deploy Storybook we trigger a build, this is done by using build-storybook
as pre script. You also need to ensure that your AWS S3 has public access allowed.
For example, my demo project is hosted at http://mokkapps-stencil-storybook-demo.s3-website.eu-central-1.amazonaws.com.
Conclusion
It is a bit tricky to combine Stencil and Storybook and it would be nice to have official documentation for this topic.
But I think it is worth the effort, and it can also improve the local component development due to Storybook's features.
The code for the demo project is available at GitHub.
If you liked this article, follow me on Twitter to get notified about new blog posts and more content from me.
Debug Why React (Re-)Renders a Component
React is known for its performance by using the Virtual DOM (VDOM). It only triggers an update for the parts of the real DOM that have changed. In my opinion, it is important to know when React triggers a re-rendering of a component to be able to debug performance issues and develop fast and efficient components.
Build and Deploy a Serverless GraphQL React App Using AWS Amplify
Recently I recognized that some SaaS (Software as a Service) products use AWS Amplify which helps them to build serverless full-stack applications. I think serverless computing will be the future of apps and software. Therefore, I wanted to gather some hands-on experience, and I built a serverless application using AWS Amplify that uses React as frontend framework and GraphQL as backend API.