Publishing a Web Components Library

Yonatan Kra
WalkMe Engineering
Published in
4 min readApr 1, 2019

Once upon a time, in order to create web components, one had to resort to a front end framework like angular or react (yes yes, I’ve heard the “it’s only a lib” before from all the angularists in the crowd) .

Web component is one awesome piece of technology (or rather, a combination of 4 technologies). Now that browser support is rising, publishing a web component to github for global consumption seems like a good contribution to the community.

In this article, we will build upon the example shown in the former article in the web components series: the modal window web component. You can read the article, or go directly to the repository on github.

We will structure a project in a scalable way, and modularize the components so that consumers would be able to consume only one component without the need to import the whole library.

Clone the repository

  1. Make sure you have git installed;
  2. git clone https://github.com/YonatanKra/web-components-ui-elements.git
  3. git checkout before_componentization
  4. yarn or npm i

You now have the repository with the modal window from the previous article. For the full result, just checkout master.

Create the main file that imports everything

Like most modern libraries, we would like to create one file where people could import all of our components in one go (a.k.a. a barrel file). In addition, we’d like to add the ability to import specific components for performance sensitive applications (a.k.a. lazy load).

We can do that by splitting our code to separate modules both in folder structure as well as in the webpack code splitting configuration.

The components folder:

Inside our src folder create a components folder. Inside create a ce-modal-window folder and copy the ce-modal-window files into it. In addition, create an index.js file there.

In the index.js file we will import CEModalWindow and define the custom element. In CEModalWindow we will remove the custom element definition.

This is how the files should look in the ce-modal-window folder:

Finally, let’s change our tests a bit to make them more robust by defining the custom element inside our spec file:

It’s the same test file, only now we are defining the custom element inside. This will enable us to do integration tests later on, for our main file, because you cannot define the same element tag on the same page and refreshing the page would cost us in test time.

All the tests pass. We can move on.

The main file

Let’s create src/main.spec.js:

Testing that the custom element is registered as expected

And now implement src/main.js that makes this test pass:

The main file would just import our components and make sure they are defined correctly. We can add more integration tests here but for now it is enough.

Anyone who requires our main.js file will get the custom elements we import to main.js.

The demo folder

For order’s sake, we will give the demo its own folder.

Move the src/index.js to a demo folder and importmain.js instead of using the standalone components:

Here’s the commit for this step.

That’s so very cool. Our tests still pass, so our app is supposed to work as expected ( npm run serve or npm run buildand then run the resultingdist\index.html).

Now we need to tell our build process to split our files so they can be consumed separately.

File splitting

File splitting in webpack is a breeze. I’ve written an article about it when webpack 3.0 was all the rage. Webpack 4 makes the whole splitting so much easier…

In our case, we’d like to do the following:

  1. Expose the main file so one could import the whole library in one go
  2. Expose each component in its own file
  3. Create the demo folder

Webpack has us covered here. We just go to the config/webpack.common.js file and change a few things:

  1. Our entry statement would now include our main module, the new demo folder and our components (currently we have only one — but we’re going to scale soon).
  2. The HTML webpack plugin now adds the HTML file inside the demo folder
  3. I’ve added a new plugin — the Clean webpack plugin, which conveniently removes the dist folder on every build

Here’s the webpack.common.js code:

If you build ( npm run build ) a dist folder will be created and you will see it, inside our folder structure.

This way, anyone using our package will be able to do import 'web-components-ui-elements’ to get our main index.js file or import 'web-components-ui-elements/components/ce-modal-window' to just get the modal window component without loading the whole library.

You can see the full commit here.

NPM configurations (a.k.a. package.json)

The package.json should point to the main file. It’s already doing that (in the main attribute). We should add a description and change the name of our module.

There are lots and lots of configurations to a package.json. You can read more about them here and modify as you like. Here’s what I came up with:

The relevant commit is here.

Documentation

Our users can’t read our mind. Let’s add documentation:

  1. Edit the README.MD file (if it doesn’t already exist, create it).
  2. Check out the github markdown page to see how to format your documentation.
  3. Let’s document our work:

4. Let’s install something that auto-creates a table of contents (TOC) for us:
`npm i -D doctoc`

5. Add a precommit hook to build the TOC inside the package.json:
`”precommit”: “doctoc ./README.md”,`

Here’s the commit for these changes: The Commit.

NPM Publish

Before we continue, please add "private": true to the package.json. Remove it when your library is truly ready to publish.

Done? Cool. This one is easy:

npm loginand follow along the instructions

npm publish

And……….. We are done!

Summary

Congratulations! You’ve just published a web component library to NPM.

You can maintain it and add more features to it.

Keep in mind that a CI/CD process should be setup, so we can manage an army of contributors to this new awesomeness.

Hope you had fun and learned something here :)

--

--