Tips to create Web components using Vue 3, TS, Vite.

nurlan_tl

Nurlan TL

Posted on December 10, 2022

Tips to create Web components using Vue 3, TS, Vite.

Recently I had a task to create a Web Component. My favorite framework is Vue 3 and I had no intentions to use another. At first glance there are a lot of videos and articles how to do it but some of them use slightly different stack and others give only part of info I needed. Finally I managed to do it and now want to share my experience.

Install Vite with Vue latest and TS support.

Create Vue SFC component to be your web component, its name should have ce.vue extension:

SampleSimple.ce.vue

We can use it inside our App.vue as any other components. And it will help us to test and debug it on developer server:

npm run dev

You implement the logic you want inside this SampleSimple.ce.vue and place any other components inside. You don't need to name child components with ce.vue extension, just usual vue extension.

Lets move to creating final web component from you vue component. First of all we need to create second main.ts file whose job is to generate final web components js file. As you can imagine its name will be:

main.ce.ts

import { defineCustomElement } from 'vue'
import SimpleSampleComponent from './SimpleSample.ce.vue'

const SimpleSample = defineCustomElement(SimpleSampleComponent)

customElements.define('simple-sample', SimpleSample)
Enter fullscreen mode Exit fullscreen mode

Our script part of package.json needs no changes:

  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview"
  }
Enter fullscreen mode Exit fullscreen mode

The most important part is vite.config.ts:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag) => tag.includes('simple-sample')
        }
      }
    })
  ],
  build: {
    lib: {
      entry: './src/main.ce.ts',
      name: 'simple-sample',
      // the proper extensions will be added
      fileName: 'simple-sample'
    }
  },
  define: {
    'process.env': process.env
  }
})
Enter fullscreen mode Exit fullscreen mode

We have changed build part, added define for process.env, and added vue compilerOptions isCustomElement to distinguish our custom element.

Thats all. Now run:

npm run build

and that will put simple-sample.js and simple-sample.umd.cjs files into dist folder.

To use our new web component you can put simple-sample.js to any place you want. Then add

<script src="path/to/simple-sample.js"></script>

to html header and use your component like that:

<simple-sample></simple-sample>

If you defined properties inside your SimpleSample.ce.vue you add properties too:

<simple-sample property1="value"></simple-sample>

What about styles? Styles that are inside SimpleSample.se.vue are included into resulting web component:

<script setup lang="ts">
...
</script>
<template>
  ...
</template>
<style>
// our web component styles
</style>
Enter fullscreen mode Exit fullscreen mode

If you import styles inside script part of the component they will be ignored by Vite build process. So the only place is styles part of SFC. Thats ok if your styles are small but if there are a lot of lines it is not comfortable to work with. So there is a solution - scss. We can use scss import and move styles to another directory and organize them in more smart manner:

<script setup lang="ts">
...
</script>
<template>
  ...
</template>
<style lang="scss">
@import '../scss/file1';
@import '../scss/file2';
@import '../scss/file3';
</style>
Enter fullscreen mode Exit fullscreen mode

Thats all. I hope this info will be helpfull.

💖 💪 🙅 🚩
nurlan_tl
Nurlan TL

Posted on December 10, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related