Web Componentsとは
Web Componentsとは、独自にカスタムしたHTML要素をカプセル化して、再利用可能にする技術です。Vue.jsなどのJSフレームワークでは一般的なコンポーネントのようなものをイメージするとわかりやすいです。
Web Componentsを利用するにあたってライブラリは不要で、JSのみで利用できます。比較的新しい技術ではありますが、2021年8月時点でのサポート状況を確認してみると、主要なモダンブラウザは一通りサポートしているようです。
使うことになった背景
親となるアプリケーション内で、別のアプリケーションを動かし、同一のアプリケーションのように振舞う仕様とする必要がありました。はじめは捻りなく、iframeでの実装を考えたのですが、フレームはデメリットも多いため、何か方法は無いかと探っていたところ、Web Componentsというワードがヒットしました。
NuxtでのWeb Components公開
今回はNuxt.jsを使用してWeb Componentsを作成し、AWSのAmplify上で公開していきます。「nuxt-custom-elements」というライブラリが用意されており、これを使うと難しいことは無く、通常のNuxt.jsアプリとして開発してカスタムHTML要素を公開することができます。以降で手順を説明していきます。
前提条件
Nuxt.jsアプリケーションを開発できる環境、およびAmplify CLIはインストール済みとします。また、私はWindows10にてWSL2を使用して動かすUbuntu 20.04にて実践しました。
参考: GitHub 公式リポジトリ
1. Nuxt.jsプロジェクト作成と nuxt-custom-elements の追加
まずは通常通り、create-nuxt-appでプロジェクトを作成します。
$ yarn create nuxt-app myapp
続いて、プロジェクトにnuxt-custom-elementsを追加します。
$ yarn add nuxt-custom-elements
たったこれだけです。
2. コンポーネントを作成する
続いて、コンポーネントを作成します。propsでタイトルを受け取り表示する、簡単なコンポーネントです。「/component/Example.vue」を作成し、下記の通り記述します。
<template>
<div class="custom-element-example">
<div class="title">
{{ exampleTitle }}
</div>
<div class="content">
<slot>Default Content</slot>
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: null
}
},
computed: {
exampleTitle () {
return this.title || 'Default Title';
}
}
};
</script>
<style scoped>
.custom-element-example {
min-width: 300px;
padding: 10px;
font-family:
'Source Sans Pro',
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
'Helvetica Neue',
Arial,
sans-serif;
font-size: 16px;
color: #35495e;
text-align: center;
background: #35495e;
border-radius: 4px;
}
.title {
margin-bottom: 10px;
font-size: 24px;
font-weight: bold;
text-transform: uppercase;
}
.title,
.content {
padding: 5px;
color: white;
background: #3b8070;
}
</style>
3. nuxt.config.jsに公開設定を追加する
nuxt.config.jsに公開するWeb Componentsの設定を追加します。
export default {
-省略-
modules: [
'nuxt-custom-elements'
],
customElements: {
entries: [
{
name: 'Example',
tags: [
{
name: 'CustomElementExample',
path: '@/components/Example',
options: {
props: {
title: 'Prop. Example Title'
}
},
slotContent: 'Slot Example Content'
}
]
}
]
},
-省略-
}
とりあえずの動作確認用に、「/pages/index.vue」を下記の通り編集しておきます。
<template>
<Example title="Prop. Example Title" />
</template>
<script>
import Example from '~/components/Example.vue'
export default {
components: { Example }
}
</script>
yarn dev を実行してアクセスすればページが表示されるはずです。
また、yarn generateを実行すると、dist配下に「nuxt-custom-elements/example」というディレクトリが作成され、その中にexample.jsというファイルが作成されるはずです。他のアプリケーションから呼び出す場合は、このファイルを読み込んで利用することになります。
ここまでうまくいったら、amplify publishでホスティングしてください。
Web Componentsの利用
ホスティングが完了したら、利用するのは簡単です。公開したjsファイルを読み込み、カスタム要素をHTMLに記述するだけです。例えば、下記のようなHTMLファイルを作成すれば、作成したコンポーネントと同一のコンテンツが表示されるはずです。
<!doctype html>
<html lang="ja">
<head><meta charset="utf-8">
<title>
</title>
</head>
<body>
<custom-element-example title="Prop. Example Title">
Slot Example Content
</custom-element-example>
<script src="https://xxxxxxxxxxxxxxxx.com/nuxt-custom-elements/example/example.js"></script>
</body>
</html>
もちろん、他のNuxtアプリからも利用できます。
<template>
<custom-element-example title="Prop. Example Title">
Slot Example Content
</custom-element-example>
</template>
<script>
export default {
head: {
script: [
{
body: true,
src: 'https://xxxxxxxxxxxxxxxx.com/nuxt-custom-elements/example/example.js'
}
]
}
}
</script>
ひとまず駆け足で公開から利用までを試してみました。
コメント