Build Vue.js Web Components with @vue/cli

A quick setup experience with Vue CLI 3 for easy development of web components

George Alan Heimel
square360

--

While a lot of attention is paid to Vue.js-based single-page apps (SPAs) and progressive web apps, one of the great things about Vue.js is the ability to make simple, small web components for non-SPA websites. This makes adding progressive enhancement to sites, which are not ready for a full SPA makeover, easy.

I needed to start creating these types of components, so I began reading all the documentation and blog posts I could google. A lot of blogs and how-tos pre-date the release of the Vue CLI 3, and some of the current documentation can be vague. This became a serious problem when I realized I was mixing example configurations from both the old and new versions of the CLI, and I had some global install conflicts too boot. Once I sorted that mess out, I was inspired to help anyone who has encountered the same issues by sharing my experience and findings.

Clean house

Once I realized I had software conflicts, I made sure to COMPLETELY un-install Vue packages that were previously installed globally. I also uninstalled for both npm and Yarn because — depending on the client’s code base — I frequently jump back and forth between these two tools.

npm uninstall vue-cli -g
yarn global remove vue-cli

I also had an old version of vue-cli-service installed globally that was causing issues. I decided to be extra thorough and delete all global Yarn and npm installs. I deleted both from my home directory.

cd ~
rm -r .yarn
rm -r .npm
rm /usr/local/bin/vue*

Be careful with this last step, especially if you have stored npm credentials for private libraries. This may have been a little extreme, but I was very frustrated with the errors and conflicts from old libraries when I followed current tutorials. This step removed any aliases that had been generated into my /usr/local/bin folder.

Get the tools

After doing this, I followed the instructions for installing the Vue CLI 3:

yarn global add @vue/cli

The new Vue CLI allows you to specify build targets, so you can develop and debug through the yarn serve command, and then later do a build to create a web component from the same code. This is great… except that the process takes a while and requires some trial and error — along with lots of digging into documentation — to find that, unless you want to use the new Vue UI, you must type the full path to the executable: .node_modules/.bin/vue-cli-service from the project root.

If you are doing this a lot, one of two things can make life a little easier. The first is edit your package.json file and change the build script to use the project local path. The second is to add a PATH modifier to your environment vars to look for the executable. I like the second method because it tends to be more flexible.

PATH="$PATH:./node_modules/.bin"
export PATH

I commonly use linting; if you do as well, you will need to install the eslint-loader package to prevent errors when you do a build command.

yarn add eslint-loader

Make the magic

Now, from the base of your project, you can run the build command with a target for web-components and it will actually work!

vue-cli-service build --target wc --name hello-world src/components/HelloWorld.vue

This will put compiled JS files into your output directory (usually dist/) that you can load into an HTML webpage. Once loaded, apply your custom tag <hello-world> anywhere within your page. You can use the App.vue file for testing and development while running the serve script. Then, compile your component entry point when ready to build. For this example, I used the HelloWorld.vue component supplied by the CLI, simplified the output and compiled it.

HelloWorld.vue from CLI create script, simplified for this example.

Since web components are meant to be encapsulated bundles of code, they do not include the Vue.js runtime, so be sure that is loaded from CDN. I also recommend a polyfill to register a custom tag, if you need compatibility with some older browsers. I use the great Web Components library for IE11 compatibility.

A sample HTML file using the web component. Vue.js is externalized when using web components, so make sure you load the Vue.js runtime from a CDN for this to work!
Output from our sample.html file.

Additional reading:

--

--

George Alan Heimel
square360

CTO Square360: technology artist, database dreamer, code monkey, knowledge collector and pie aficionado