Codementor Events

Web Components with Vue CLI 3

Published Mar 15, 2019
Web Components with Vue CLI 3

Among the plethora of features that come with the newest version of the command line interface of the JavaScript framework Vue, there's one that I find pretty impressive, and that is the ability to package a single file component (SFC) as a Web Component. What's that? Basically a way of creating your own HTML tags. Let's see how to make a project and add some goodies to make working in your WC an enjoyable experience.

The first thing you need is, of course, the Vue CLI 3. You will find instructions on how to install it in its website. You won't need a full blown project just to make a WC, so just create a new directory and get inside it.

mkdir my-awesome-component && cd my-awesome-component

The minimum necessary for this kind of project is a .vue file. Let's create one.

touch MyAwesomeComponent.vue

If you're already familiar with Vue SFCs you know how they're structured. Let's add some code to start seeing some progress.

<template>
  <p>Hey you!</p>
</template>

You're done! Let's build this and see how it looks.

vue build --target wc --name my-awesome-component MyAwesomeComponent.vue

If you have any luck you'll now have a dist folder with the built files. You get a .js file with everything inlined (ok, there's not really much to inline yet) and a demo.html file which you can open right away to test your component. If you open the demo.html file in your editor, which I know it's Sublime Text, you'll see that it's loading Vue. Web Components like this rely on Vue being globally available to work.

I can hear you in the back. "Oh that's it?! You better tell me something more useful or start thinking on how you're gonna give me my time back!"
Ok ok, I'll try. Let's add some functionality to this. After all, we're using Vue here, and it would be cool if we write some JavaScript at least. We'll add script to our SFC something just to verify everything is in place. Let's just go full hardcore and write some ES6.

<template>
  <p>{{ msg }}</p>
</template>

<script>
export default {
  data () {
    return {
      msg: 'Hey you!'
    }
  }
}
</script>

We can replay our build command now. But not so fast, if you do, the CLI will shout at you saying that you don't have babel-loader installed. Webpack (in which the whole CLI is based) needs it to transpile your beautiful ES6. How would we do that? Just create a package.json file with your preferred package manager.

yarn init

You can hit the enter key until the end, the CLI will ignore the entry point anyway. And now, add babel-loader as a dev dependency.

yarn add babel-loader --dev

Are we there yet? No! Try to build again and it will tell you that you also need @babel/core. Just install it like before.

yarn add @babel/core --dev

Try to build again and now you have it, your own Web Component running Vue and with ES6 support.

Still not impressed. Ok, then let's add support for Tailwind CSS. For those of you who don't know, Tailwind is a PostCSS plugin that generates utility classes from a .js configuration file, giving you the most possible flexibility. The Vue CLI 3 can handle PostCSS configuration via a RC file, so if you're wondering why, I'd say why not? We'll start by adding the tailwindcss package.

yarn add tailwindcss

The PostCSS configuration file.

touch .postcssrc.js

And the default tailwind.js file.

./node_modules/.bin/tailwind init

Now in the PostCSS configuration add

module.exports = {
  plugins: [
    require('tailwindcss')('./tailwind.js')
  ]
}

And in our .vue file add a style block

<style>
@tailwind utilities;
</style>

Let's use some of the tailwind classes just to make sure everything works

<p class="text-teal">{{ msg }}</p>

Build again and there it is! Your Vue and Tailwind powered Web Component! But wait! The CLI is telling you that your component is exceeding the recommended size limit, and that's because Tailwind adds a lot of classes that you're not really using. Luckily there's a solution for that: Purgecss. Purgecss is a webpack plugin that can scan your files for unused classes (or used classes to be correct) and remove every inch of css that you're not using, bringing the file size to a minimum. I think you can configure it as a webpack plugin, but let's use here the PostCSS version of it.

yarn add @fullhuman/postcss-purgecss --dev

And add it to the PostCSS configuration, the whole file should be like

module.exports = {
  plugins: [
    require('tailwindcss')('./tailwind.js'),
    require('@fullhuman/postcss-purgecss')({
      content: ['./*.vue'],
      extractors: [
        {
          extractor: class TailwindExtractor {
            static extract(content) {
              return content.match(/[A-z0-9-:\/]+/g) || [];
            }
          },
          extensions: ['vue']
        }
      ]
    })
  ]
}

Build again and now we're really done. You can now start building your own Vue and Tailwind powered components and distribute them having minimum file size.

Hope you enjoyed this recipe!

Discover and read more posts from Martín Aimar
get started