Edited at

Development of Custom Element using Vue.js #kyotojs

このスライドは社内勉強会で発表しようと思って作ったけど、年末でほとんど人がいなかったので供養として #kyotojs vol.15 で発表したものとなります。



  • potato4d


    • real name: HANATANI Takuma



  • organizations


    • ElevenBack (self-employed)

    • LINE Corp



  • Maintainer at


    • vuejs/jp.vuejs.org

    • nuxt/docs



  • Web Application Developer


    • ♥ Vue.js, Nuxt.js, Node.js(w/ TypeScript), Serverless

    • ♥ User interface, Micro interaction, Product development





今日話すこと


  • 開発したものデモ

  • Web Components - Custom Elements の開発手法について

  • Vue CLI v3 を利用した、 Vue.js ベースの Custom Elements 開発

  • 実際の開発フローについて

  • Vue.js での開発フローの罠

  • 使いどころ



注意


Screen Shot 2018-12-28 at 12.47.50.png



開発したもの



Kamishibai Viewer

Image from Gyazo


  • アドカレのネタ

  • Qiita のスライドモードの埋め込みビューアー

  • SlideShare / Slides.com / SpeakerDeck はサクッと埋め込めるけど Qiita は無理だった

  • OSS で作ったらみんな嬉しそうなので開発

  • Vue.jsで作られている



Custom Elements の開発手法

そのままやるなら



  • lit-html


    • 一番薄い

    • そこまで嬉しくはない




  • lit-element


    • 人間向き

    • class & render 関数

    • 最近 rc が出てそろそろ stable に?





Custom Elements の開発手法

フレームワークでやるなら(1)



  • Angular Elements


    • Angular で作れる

    • まだばりばり開発中(らしい)

    • バンドルサイズがでかい(Angular全部入る)

    • Ivy がきたら min 12kb からになる(らしい)





Custom Elements の開発手法

フレームワークでやるなら(2)



  • Vue CLI v3


    • Vue.js で作れる

    • バンドルサイズはマシ(でもまぁフルで入る)

    • ちょっと癖がある





言いたいこと→Custom Elements はフレームワークで作れる



Vue CLI v3 での開発



ざっくりと手順



環境の構築


terminal

$ vue create my-wc-project

$ yarn add @vue/web-component-wrapper



package.json の編集


package.json

{

"name": "my-wc-project",
"scripts": {
"build": "VUE_CLI_CSS_SHADOW_MODE=true vue-cli-service build --target wc --name my-component ./src/wc.ts",
"...": "..."
},
"...": "..."
}



専用の Entrypoint の作成


src/wc.ts

import Vue from 'vue'

// TS の定義はない
const { default: wrap } = require('@vue/web-component-wrapper')

// ?shadow を使って Shadow DOM での Scoped CSS を有効化するのでこう読む
const { default: MyComponent } = require('./MyComponent.vue?shadow')

window.customElements.define('my-component', wrap(Vue, MyComponent))




コンポーネントのスクラッチ


src/MyComponent.vue

<template>

<div>
<p>
<span>Hi, {{username}}</span>
</p>
</div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
props: {
username: String
}
})
</script>

<style scoped>
p span {
padding-bottom: 8px;
border-bottom: solid 2px #77CB5B;
}
</style>




ビルド


terminal

$ yarn build




:tada: 完成 :tada:

Screen Shot 2018-12-28 at 14.55.16.png



実際やってみる(時間があれば)



スライドだけみてるかたは⇣

https://github.com/potato4d/vue-cli-wc-export-minimal-example



……



……で、これなにが嬉しいんだっけ



Custom Element の嬉しさ(1)


  • (半)静的コンテンツへの埋め込み


    • 今回の Embed みたいに SPA とは疎結合で使いたいものは良さそう

    • Twitter Button は Web Components 製

    • Ad とかには最適なのでは



  • 内部実装の共通化


    • 最終的に出てくるのが WC という共通言語なら技術間の取り回しが良い

    • けどこれはまだまだ先だと思う





Custom Element の嬉しさ(2)


  • メモリから素直な DOM の世界に


    • 仮想 DOM とかの都合もあって今は Fw のメモリ上に DOM がある

    • 隔離された空間から public な DOM になるのは良し悪し含めある



  • Shadow DOM(Scoped CSS) 周りの統一


    • 仕様上は Shadow DOM に統合されている(2018/12現在)

    • ようやっと Fw によるオレオレ Scoped CSS じゃなくなる?





その他所感


  • 正直 SPA 作るだけなら Fw から吐き出せても「それで?」感

  • Embed / Ad などでは普通に使われそうなので良いのでは

  • Draggable みたいな Vanilla & Fw wrapper の世界にはまだ早そう


    • ああいうのはラッパーが便利な点に価値が



  • 一応多少触っておくと雑談力にはなりそう 



Thanks