Typescriptで開発してJSファイルだけでWeb-Componentsを提供できる様な開発環境を構築する

## TL;DR
Web-Components、とっても素敵なんですが、いまいちまだその真価がわからないってことが多いかと思います。
どんなユースケースが直近でweb-Componentsを使えるようになったら有用なのか？Webの開発者に喜ばれるのか？

と考えたとき、
*「JSのファイルを読み込んでタグを書くといい感じのUIが提供される」* 
のが一番シンプルで楽なんじゃないかと思い。

`<template />` を使わずWeb-ComponentsはJavascriptで完結できる開発環境を作ってみよう。
ということで、この記事です。

## 主要なライブラリ
※ 結論からすると [まったり開発しているリポジトリがあるので](https://github.com/uruha/dev-component) いろいろぶっ飛ばしてソース読んだほうが早いって方はどうぞ。

現行で使ってるライブラリは以下です。

```
- Lit-html
- Typescript
- Rollup
- (Gulp)
```
かなりシンプルですが、これで `<template />` を使用せず、最終的にバニラなJavascriptでWeb-Componentsを提供できるコードが書けます。楽！

## 各論
### Lit-html
ES6でWeb-Componentsを実装するのであれば全然書けるのですが、どうしても `<template />` でコンポーネントを定義するところが厄介です。理由としては、

- UIだけhtml側に行ってしまうので、ファイルが分断されたりする可能性がある（underscoreやlodashの時はそのほうが良かったたのに、人間ってば自分勝手ね）
- `<template />` で定義しているhtmlの中に動的に値をアタッチしたい（この場合 `<template />` を使用するとかなり面倒くさいです）

個人的にこの２点がReact, Vueとか通った身だと「面倒」と思ってしまうのです。
そこで、 `Lit-html` を使います。 `Lit-html` は特にVDOMでも何でもなく、Web-Componentsの `<template />` の箇所をJSで書けるようにしてくるものなので、使い勝手も楽ちん。こういうかゆいところに手が届くライブラリはいいですね。

### Typescript
上記のリポジトリの他に会社で全く同様の内容をbabel (babel v7/ES2015) を用いてやっていて個人はTypescriptでやってみようというノリです。
深い意味はありません。。。

### Rollup.js
Webpackのあの割れ窓感があまり好きではなく (もちろん業務では触りますよ) 、なにかもう少しJSとかだけ上手く取扱できるやつないかなーと思って今回使ったのが `Rollup.js` です。

[サイバーさんのこれ](https://logmi.jp/tech/articles/295673) とかも読んでみて、なんとなくライブラリとして将来的に提供するなら `Rollup.js` でいいんじゃないかなーという感じで採用しています。

### Gulp
Webビューの確認で使ってるだけです。
トランスパイルされたJSが更新されたらブラウザも更新して欲しい私にとってとりあえず入れてるやつです。

ただ、Rollup.jsと連携はさせないであくまでビューの確認に使っています。

## 環境構築やってき
Typescriptやらの基本的な設定は、いろんな方が書いている・既にやられていると思うので割愛しますが、 `typescript-lit-html-plugin` は必須なので、忘れずにインストールして下さい。

```json:tsconfig.json
{
    "compilerOptions": {
        "target": "es2015",
        "moduleResolution": "node",
        "removeComments": true,
        "noImplicitAny": false,
        "noLib" : false,
        "declaration" : false,
        "preserveConstEnums": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "suppressImplicitAnyIndexErrors": true,
        "sourceMap": false,
        "allowSyntheticDefaultImports": true,
        "plugins": [
            {
                "name": "typescript-lit-html-plugin"
            }
        ]
    }
}
```

次にロールアップですがトランスパイル用の　`rollup-plugin-typescript` がお亡くなりになられているので、 `rollup-plugin-typescript2` を使用して下さい。これは大きなお友達とのお約束です。コンフィグは以下のようになります。

```javascript:rollup.config.js
const resolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const typescript = require('rollup-plugin-typescript2');

export default {
    input: './src/index.ts',
    output: {
        file: './dist/index.js',
        format: 'cjs'
    },
    plugins: [
        resolve({
            browser: true,
            jsnext: true,
            preferBuiltins: false,
            extensions: ['.ts', '.js', '.json']
        }),
        commonjs({
            include: 'node_modules/**'
        }),
        typescript({
            tsconfigOverride: {
                include: ['src/**/*.ts']
            }
        })
    ]
};
```

`format` などはライブラリのことを見込んで `cjs (commonjs)` にしています。
ココらへんは目的に応じて変更が可能です。

基本的な設定はこのくらいです。

あとは `tslint` なり `prettier` なりご自分の好きな色に染めて下さい。
Webビューに関しては、Rollupで生成したJSをhtmlで読み込んでタグを書いて実行するだけです。
とってもシンプルでしょ？

## おもうこと
デザイナからこの業界に入った身としては、もし当時（４年くらい前）からWeb-Componentsが使えたら、今で言うjQueryのスライダーやそういうのがもっとシンプルに実装サイドで提供できたのではないかなー？と思っています。

今回、このゆるい開発を進めているのも先の思いがあってのことです。

リポジトリのベースのelement classは　@aggre さんの [FrameOO](https://github.com/frame00/oo-elements) を参考にしています。ほんと勉強になります。

ということで、Web-Componetsいろいろと動きがありそうですが、
以外に簡単にJSオンリーで実装始められるので、試してみてはいかがでしょうか？ということでした！

それでは！