Integrating Stencil with Storybook
Today I set up a new Stencil project with Storybook to build web components with. However, I had a hard time trying to get the hot module replacement (or live reloading) to work in Storybook. When using the standard dev
build process, Stencil will omit the needed esm loader that Storybook’s webpack server will use to determine if a module has changed. Since I wanted to have instant feedback when developing components with Stencil, I tried to find a way to integrate both tools.
Loading Stencil components in Storybook
The most common way I found to load Stencil components in Storybook is to just setup a Stencil components
project and use the Storybook HTML project setup. Then, one can load the built components by including a preview-head.html
like so:
<script type="module" src="./stencil-components/stencil-components.esm.js"></script>
<script nomodule="" src="./stencil-components/stencil-components.js"></script>
Now, when running start-storybook -p 6006 -s dist
, Storybook will happily include the components and load the stories. However, since this tells Storybook to load the components as static assets, the hot reloading won’t work.
Making hot reloading work
In order to include the Stencil components in webpack’s dependency graph, we need to load the components through a JS file. To do so, we’ll add a preview.js
file in Storybook’s config directory .storybook
in your project. The JS code in this file will be added to the preview canvas of every story and – most importantly – be recognized by the webpack build — which is exactly what we need.
When running Stencil’s build process with the --watch
flag, it will produce the correct dist
-output containing the esm/loader.mjs
file. We’ll then use this file to call the defineCustomElements()
function, which registers all of our app’s components. See the full contents of the preview.js
file below:
import {defineCustomElements} from '../dist/esm/loader';
defineCustomElements();
The generated default scripts section of the project’s package.json
file doesn’t contain the correct build script just yet, though. So you will need to add the following line to the scripts
section:
"build.watch": "stencil build --watch"
And that’s it! You should now see all of the changes made to your components reflected in Storybook. To run both the build and Storybook, simply run these two scripts in parallel:
npm run build.watch
npm run storybook
Demo Repository
If you want to skip the hassle of implementing this in your live project and just see if it works, I’ve prepared a repository for you. 🙂