In the last months, I've been digging in how to mix two of my favourites "technologies" of recent times. Web components and Typescript.
I understand web components as they are described in their MDN page
Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps.
So, in my opinion, they are not something that going to replace frameworks like React or Angular, but a way to create reusable pieces of code that you can use independently of your front-end stack.
So, you will say, it's easy, start to write your components with typescript and then transpile and serve them...
and that's how my project started...
Soon in my project I wanted a way to serve my component as a single file, but separate my HTML and CSS in different files when developing, or use lit-html for the templates, and hot-reload when developing and an option to bundle everything to serve it in production... so I started to experiment with webpack (and changed it later with rollup).
I wanted as well a way to do tests, so I ended using karma and jasmine.
I wanted a way to have a component gallery, so I integrated storybook.
At the end I wanted to upload the result components to npm, so needed to create a package.json and a README.
And all that is what included out of the box in what I've called "wc-base-typescript" (Original, I know :)).
This project allows you to start writing you web components with typescript in one minute (depending on your internet connection) and have ready for you all the functionalities I described above.
Do you want to test it or use it in your next web-component projects? Keep reading or go directly to the wc-base-typescript github repository as it's more or less the same but with fewer words.
Of course, don't forget to give the project an star in github if you think it deserves it!
And if there is something you think can be done in any other (or better) way, don't hesitate to tell me in the comments or send me a PR, collaboration is more than welcome :)
Ready? Let's go!
First thing. It's better if you copy the repository and make your own for your project. You can always download the code but I recommend to use degit or any similar tool for convenience.
npm install -g degit #In case you don't have it installed degit tx2z/wc-base-typescript
Once the project is on your computer, enter the folder and install all npm dependencies:
And you can start to write your components! I told you 1 minute :)
All the components you're going to create will be stored in src/components.
I've created in the project three components to show the different options available:
The base-component generates a web component with no dependencies or libraries.
The lithtml-component generate a web component using lit-html as template library.
The noshadow-component generate a custom element (not sure if it can be called a web component) without using the shadow DOM & with no dependencies or libraries.
For a quick start, you can copy the content of one of the example components and change what you need.
It's important as well to include your defined custom element in public/index.html so you can test it while developing. If you open it you will see that I've included the three example components there.
Then, to run a server in development mode you only have to type in your terminal:
Rollup will transpile and pack your components and reload the page every time you save a file.
That's it. Nothing to configure or to do other than focus in your code!
So maybe you want to add some test to your components to avoid problems when the code-base start to grow... or, even better, you're a super-developer that like to write your code following the Test-driven development (TDD) process.
I had some hard time trying to add test to my previous web component projects, but, again, now everything is pre-configured and works out of the box. Karma & jasmine are included as testing environment and framework.
Inside your component folder include a file ending with "spec.ts" and write your tests (with typescript). Of course, there are some examples in the example components.
By default, launchers for chrome and firefox are already installed and configured (your test will be launched in both browsers) but you can install and use any other karma-launcher if you want.
To execute the test use:
Karma has as well live-reload, so if you change your components or test files the test will be executed again.
Just a little warning here, storybook uses webpack and, when building, rollup will be used... the result should act and look the same but it's not exactly the same.
Storybook for HTML is used and tuned so no further configuration is needed to use it for your components. The following storybook addons are included:
Knobs: Allows edit web components' props dynamically using the Storybook UI.
Viewport: Allows web components to be displayed in different sizes and layouts in Storybook. This helps build responsive web components inside of Storybook.
A11y: Helps to make your web components more accessible.
Notes: Allows to write notes or documentation for your web components.
This is a standard storybook installation. You can add other addons or configurations that suit your needs.
There are two files inside the example components that are used by storybook.
@component.stories.ts: Is the file to create a story for your component. You can check storybook documentation about how to create stories starting here
README.md: It's used to add documentation for your component using the Notes storybook addon.
Storybook will use these two files to generate the stories and the documentation. Once these two files are present run storybook with:
npm run storybook
Again, examples of all this can be found in the example components provided :)
To build a static storybook app ready to be deployed run:
npm run storybook-build
You can find your storybook builds in the "dist-storybook" folder.
If you want to publish your storybook in github pages I recommend you to install storybook-deployer. It will do all the work for you.
Note that storybook is completely optional. If you're not using it you can remove (or not create) the @component.stories.ts files. Even you can remove all the storybook and webpack references in the package.json to completely remove storybook from your project.
So it's time to build your components to use them elsewhere. Fear not, just run:
npm run build
You can find your builds in the "dist" folder.
Your components will be compiled as js file (as ES module), to use them as modules in your application, and in a dist.js (as iife), to use them directly in browsers, with the same name you give to the folder in src/components.
All modules will include their respective Typescript declaration files in case you or others want to use them with typescript.
The webcomponents polyfills will be included as well in the "dist" folder, you can use them or load directly the code from a CDN such as unpkg: https://unpkg.com/@webcomponents/webcomponentsjs@^2/
So that's it take your components and use them whatever you want. Just copy-paste the version (ES module or IIFE) that you need in your project and use it.
No, that's not how things work nowadays, I know. The wc-base-typescript simplify as well all you need to...
You may have seen that a README and a "package.json" are included as well in every example component folder. Rollup will copy these files to the "dist" folder and add some important info to the package.json.
In other words, you don't need to worry about the main, module or type properties, as they will be filled automatically, but you need to provide the rest of the information in the package.json.
All you need to do to publish your component in NPM is to enter the component folder inside "dist" your terminal and:
Of course, you need to have an account in npm and login into it in your terminal before that. I recommend reading the how-to in the npm docs before publishing a package.
Once your package is in npm it can be installed and used as any other npm package. The ES module version will be the default.
So with the wc-base-typescript project you can quickly create, test and build for production and publish web components, and optionally create a components gallery to show them up.
If you want to see one of the uses I give it to it you can check my Creative Commons license generator as web component with his galery and repository. I created it (all included) in around 6 hours of intermittent work.
What do you think? Can it be useful for you?
PD: Don't hesitate to tell me if you use it for any of your projects, I will love to know about what are you creating with it :)
PD2: And again, if there is something you think can be done in any other (or better) way, don't hesitate to tell me in the comments or send me a PR :D