🚀

Vue 3 で Web Components を実装しCDN で配信する

2024/09/24に公開

この記事を読み、Vue 3 で Web Components を配信する方法が気になったため、手順を記載します。
https://zenn.dev/comm_vue_nuxt/articles/improvements-to-custom-elements-in-vue3-5#custom-element%3A-useshadowroot()-helper

Vue 3 で Web Components を実装する

プロジェクトの作成から Web Components の実装までを記載します。
今回は、*.ce.vue の拡張子で Web Components の実装を行います。
なぜ *.vue ではなく *.ce.vue の拡張子を利用するのか、詳細は こちらの記事 をご参照ください。

Project の作成

Vite を使用して、Vue プロジェクトを作成します。

npm create vite vue-web-components-example --template vue-ts

作成したプロジェクトから、以下のファイルを削除します。

├── public/
│   └── vite.svg
└── src/
    ├── assets/
    │   └── vue.svg
    ├── components/
    │   └── HelloWorld.vue
    ├── App.vue
    └── style.css

Web Components を実装する

src/componentsCounter.ce.vue ファイルを作成します。

└── src/
    └── components/
        └── Counter.ce.vue

作成した Counter.ce.vue へ以下を記述します。

src/components/counter.ce.vue
<script setup lang="ts">
import { ref } from 'vue'

defineProps<{ msg: string }>()

const count = ref(0)
</script>

<template>
  <h1>{{ msg }}</h1>
  <button type="button" @click="count++">count is {{ count }}</button>
</template>

<style scoped>
h1 {
  font-size: 3.2em;
  line-height: 1.1;
}

button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #797979;
  cursor: pointer;
  transition: border-color 0.25s;
}
button:hover {
  border-color: #646cff;
}
button:focus,
button:focus-visible {
  outline: 4px auto -webkit-focus-ring-color;
}
</style>

ここまでの作業で Web Components の実装は完了です。

Web Components を Custom Elements へ登録し、動作確認を行う

実装した Web Components を Custom Elements に登録し、ローカル環境で動作確認を行います。

Web Components を Custom Elements へ登録する

src/main.ts の中身を以下コードへ置き換えます。

src/main.ts
import { defineCustomElement } from 'vue';
import Counter from './components/Counter.ce.vue';

// Custom Element のコンストラクタに変換
const CounterElement = defineCustomElement(Counter);

// Custom Element として登録
customElements.define('counter-element', CounterElement);

登録した Custom Elements を使用する

index.html の中身を以下コードへ置き換えます。

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue 3 Web Components Example</title>
  </head>
  <body>
    <!-- 先ほど Custom Elements へ登録したコンポーネントを記述  -->
    <counter-element msg="Sample"></counter-element>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

Web Components の動作確認を行う

ローカルサーバを起動します。

npm run dev

画像のような画面を表示出来れば実装完了です。

Web Components を Build する

CDN で配信を行うために、Web Components を Build できるようにします。

Build 用の設定を追加する

vite.config.ts の中身を以下コードへ置き換えます。

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

// https://vitejs.dev/config/
export default defineConfig({
  define: {
    // NOTE: Vite で Build した際に発生する `Uncaught ReferenceError: process is not defined` エラーを回避するために追加。
    //       https://github.com/orgs/vuejs/discussions/8322
    "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
  },
  build: {
    lib: {
      entry: ["./src/main.ts"],
      name: "MyWebComponents",
      fileName: (format) => `vue-web-components-example.${format}.js`
    },
  },
  plugins: [vue()],
})

TypeScript を利用していると、process に対してエラーが発生するため @types/node を追加してください。

npm install --save-dev @types/node

Build を行う

以下を実行し Build します。

npm run build

CDN で配信する

CDN で配信するために必要な修正、配信、動作確認を行います。

package.json を修正する

package.json から private を削除します。

package.json
  "private": true,

package.json へ以下を追記します。

package.json
  "main": "dist/vue-web-components-example.umd.js",
  "module": "dist/vue-web-components-example.es.js",
  "unpkg": "dist/vue-web-components-example.umd.js",
  "files": [
    "dist"
  ],
  "publishConfig": {
    "access": "public"
  }

CDN へ配信する

npm へログインします。

npm login

ログイン後にパッケージを配信します。

npm publish

配信したパッケージの動作を確認する

index.html の中身を以下コードへ置き換えます。

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue 3 Web Components Example</title>
  </head>
  <body>
    <counter-element msg="Sample"></counter-element>
    <!-- src に設定する URL は `https://unpkg.com/パッケージ名@バージョン/ファイル名` で読み込みを行うことが出来ます。 -->
    <script src="https://unpkg.com/@l4dybird/vue-web-components-example@0.0.2/dist/vue-web-components-example.umd.js"></script>
  </body>
</html>

ローカルサーバを起動します。

npm run dev

Web Components 描画を確認できれば完了です。

今回作成したリポジトリ

https://github.com/l4dybird/vue-web-components-example

Discussion