◆ Chrome だと簡単
  ◆ ビルドするのも最小限のモジュールのパスを変換するくらい
  ◆ CDN に頼れば HTML ファイルを書くだけでビルドもインストールも不要
◆ IE11 だと polyfill 入れたりオプション設定したりですごく大変
  ◆ うまく動かないときの調査も大変

lit-element のドキュメントを見てみると IE も対応と書いてたので IE でも WebComponent がいい感じに動くのかなーと気になったので試してみました

結構苦戦したのでやっぱり IE 対応はしなくていいやというのが結論です
ほとんどは IE 対応と書いてる割に対応するための方法がドキュメントになく readme には webcomponentsjs が必要くらいしか書いてないのが原因なので一度わかれば次からはそこまで困らないのですが それでもやりたいとは思えない手間の多さです

Chrome の場合

まずは Chrome でやってみます
とりあえずインストールします

yarn add lit-element

parcel や webpack でも良さそうですが polymer プロジェクトなので polymer-cli を使ってビルドします
公式チュートリアルもこれですから

yarn global add polymer-cli

でインストールしたら

polymer build --entrypoint le-test.html

でビルドします
エントリポイントの HTML は le-test.html にしています

モジュールのロードは file プロトコルじゃうごかないので build/default フォルダを適当な簡易サーバで公開します

php -S localhost:8000
py -m http.server

あたりで

ソースは単純なコンポーネントひとつだけにしてます

le-test.html
<!doctype html>

<script type="module" src="index.js"></script>

<test-element></test-element>

index.js
import "./test-element.js"

test-elem.js
import { LitElement, html } from "lit-element"

// 日時を表示して自動で更新するコンポーネント
customElements.define(
"test-element",
class extends LitElement {
static get properties() {
return {
time: { type: Date },
}
}

constructor() {
super()
this.time = new Date()
this.tid = null
}

connectedCallback() {
super.connectedCallback()
this.tid = setInterval(() => (this.time = new Date()), 1000)
}

disconnectedCallback() {
super.disconnectedCallback()
clearInterval(this.tid)
}

render() {
return html`
<p>Time: <span>${this.time.toLocaleString()}</span></p>
<style>
span {
font-size: 1.2;
color: red;
}
</style>
`
}
}
)

これで localhost:8000 の /le-test.html を開くと毎秒現在時刻が更新されるページが表示されます

polymer-cli だと開発用にサーバ機能と自動で更新される機能もあります

polymer serve

ビルドしたものは

import { LitElement, html } from "./node_modules/lit-element/lit-element.js";

のように自動でパスが変更されます
それくらいでバンドルされるわけでもなくそれほど変わりません

CDN

一応ビルドしましたが Chrome なら CDN からロードするだけで済ませられるので polymer-cli や npm (yarn) がなくても使えます
すごくシンプルな例だとこれで十分です
これを HTML ファイルに貼り付けて開くだけでビルドもサーバもいらずです

<!doctype html>
<script type="module">
import { LitElement, html } from "https://unpkg.com/lit-element/lit-element.js?module"

customElements.define(
"test-element",
class extends LitElement {
render() {
return html`
<h1>test</h1>
`
}
}
)
</script>
<test-element></test-element>

IE11 の場合

serve まで

IE11 だと WebComponent に対応していないので polyfill が必要です
追加で @webcomponents/webcomponentsjs をインストールします

yarn add @webcomponents/webcomponentsjs

HTML にこれをロードする script を追加します

le-test.html
<!doctype html>

<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script type="module" src="index.js"></script>

<test-element></test-element>

bundle のほうは全部入りで loader の方は必要なものだけロードするというものです
Chrome などモダンブラウザを重くしたくないので loader の方を選びました

これを忘れると 「'Promise' は定義されていません」とエラーが出ます

polymer serve 

の場合はブラウザによって自動で必要な処理をしてくれるので ここまでの変更だけで IE でも Chrome のように時刻表示できるようになります

build も

polymer の簡易サーバ以外で動かすには build しないといけないですが
build の場合はこれだけだと動きません

ES5 じゃないと動かないので

--js-compile



--js-transform-modules-to-amd

が必要です

--js-compile では ES5 に構文を変換します
--js-transform-modules-to-amd では es modules を amd 形式に変換します
こっちもやらないと import などで構文エラーになります

さらに --extra-dependencies に

node_modules/@webcomponents/webcomponentsjs/**

が必要です
loader からロードする部分は静的解析されないので自分で設定してビルド時に含めるファイルに追加しないといけません
これがないと polyfill が追加されないので「'Promise' は定義されていません」とエラーが出ます

polymer build --js-compile --js-transform-modules-to-amd --extra-dependencies node_modules/@webcomponents/webcomponentsjs/** --entrypoint le-test.html

ここまでやって やっと IE11 で動きます
ES5 変換とかあるので Chrome でもレガシーコードが動くのでパフォーマンスを考えるなら別々のビルドを用意して polymer serve のようにクライアントに応じて出し分けるのがベストのようです
いらないものがごちゃごちゃあると Chrome でのデバッグも大変になりますからね

polyfill

これで動きはしましたが 完璧ではありません
webcomponents 用の polyfill のみなので Promise など一部の機能と構文変換だけです
構文変換があるので {...foo} や () => {} や `tpl str` などは動くのですが Object.entries や includes メソッドみたいな polyfill ライブラリは含まれません

includes などの JavaScript 自身の機能の polyfill
remove や closest みたいな DOM 系の polyfill
fetch などのその他 web api の polyfill

は別途必要です

Shady DOM / Shady CSS

動いたのは良いのですが ShadowDOM ってどう実装されてるんだろう?と IE で devtools を開いてみたら ShadowDOM の部分はどこにも表示されていません

shadydom-ie11

要素の選択で画面上を選択したり 要素を右クリックして要素の検査をクリックしても表示されません
test-element の shadowRoot プロパティを経由したらアクセスはできました

IE の機能だと devtools の機能で調査は難しいのでソースを探したのですが規模が大きくて探すのが大変だったので Chrome で動かしてみました
Chrome でも

ShadyDOM = {force: true}

を最初に定義しておけば強制的に ShadyDOM による ShadowDOM が作られるので調査しやすいです

Chrome でみてみると

shadydom-chrome

普通に test-element の内側にありました
ただ test-element の children は空ですし childElementCount は 0 です
test-element の内側にある p の parentElement も null でした
実際には test-element の中にあるのでレンダリングされているものの children や parentElement を書き換えて取得できなくしてるようです
IE は実際の構造ではなく DOM のプロパティを元に devtools の表示も行っているので表示されないということでしょう

CSS のスコープは再現するために CSS の中身や HTML のクラスが書き換えられてます
CSS はただの span だったのに span.test-element になっていて p には test-element というクラスが追加されていました
ランダムな文字列とかではないので 重複しないように自作要素のタグ名をクラスにつけない方が良さそうです
HTML チェックしてたとしても文字列から動的につけられるクラス名は無理がありますしね