◆ lit-html だと lit-element とか WebComponents 使わなくても結局 webcomponents の polyfill が必要
◆ 入れると lit-element のときと同じくスタックオーバーフロー
◆ 手間が不要な hyperHTML のほうが楽

最近なんとなくで IE11 を試してみたら動かないのばかりで 諦めては あれも試してみようとかでなんか IE11 をいじってます

lit-element というか WebComponents はまともに動かなかったので(polymer build なら動きはしたけど不満点も多い) 諦めて WebComponents を使わず単に lit-html を使ってみようとしました
公式サイトに IE 対応とは書いているものの 手順が書いてないんですよね

lit-html

webpack

parcel は前記事でも書いた通り node_modules 以下はトランスパイルしてくれないので webpack を使います

test.html
<script src="test-bundle.js"></script>

test.js
import {html, render} from "lit-html"

const update = f => render(html`<h1>${f()}</h1>`, document.body)

setInterval(update, 1000, Date.now)

webpack.config.js
module.exports = {
mode: "development",
entry: "./test.js",
output: {
path: __dirname,
filename: "test-bundle.js",
},
devtools: false,
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
],
},
],
},
}

package.json
{
"dependencies": {
"lit-html": "^1.1.0"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"babel-loader": "^8.0.6"
},
"browserslist": [
"IE 11"
]
}

とりあえず最低限のものです
JavaScript の処理は単純で lit-html の render で毎秒 Date.now() を値を画面に表示します

これを webpack でバンドルします

polyfill

バンドルしたものを IE11 で実行してみると assign がないとエラーです
Object.assign など ES2015+ の機能が入っていないからのようですね
仕方ないので @babel/polyfill をインポートします

yarn add -D @babel/polyfill

して test.js の最初に

import "@babel/polyfill"

を追加します

これで再度 webpack して IE で開いてみると

NotSupportedError

エラー箇所を確認すると document.createTreeWalker でした
IE は対応してないんですね
DOM の polyfill まで必要そうです
これだけ というのがなさそうなので lit-element が動いている webcomponents の polyfill が必要そうです

なんかイヤな予感はしますが @webcomponents/webcomponentsjs をインストールして

<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>

を HTML の最初に追加したら……

スタック領域が不足しています。

前記事のときと同じ結果です
結局 lit-html も動かせませんでした……

hyperHTML

hyperHTML も IE11 に対応しているので試してみます


test.html
<script src="test-bundle.js"></script>

test.js
import {bind} from "hyperhtml"

const update = f => bind(document.body)`<h1>${f()}</h1>`

setInterval(update, 1000, Date.now)

webpack.config.js
module.exports = {
mode: "development",
entry: "./test.js",
output: {
path: __dirname,
filename: "test-bundle.js",
},
devtools: false,
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
],
},
],
},
}

package.json
{
"dependencies": {
"hyperhtml": "^2.29.0"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"babel-loader": "^8.0.6"
},
"browserslist": [
"IE 11"
]
}

最初に書いた lit-html のものとほぼ一緒で polyfill とかを入れてない状態です
test.js の書き方を hyperHTML ように置き換えたくらいです

これを webpack して実行してみると……普通に動きました
特に追加の polyfill もいらずです

コードを見てみると hyperHTML では内部 (依存パッケージの @ungap/***) に polyfill を持っています
ただ polyfill と言っても モダンブラウザと同じように標準機能として扱えるように拡張するわけではなく モジュールとしての提供で 機能が存在すればそれをそのまま返して 存在ない場合は独自実装したものを返す作りです
このモジュールをロードして使わない限りは IE は IE の機能ままなので 別の polyfill と競合したりはしません
こういうの ponyfill とかいうのでしたっけ?

とりあえず 親切に内部で対応してくれているので 使う側は ES5 にトランスパイルするだけで特に polyfill 入れたりを考えずに使えます
IE11 対応するなら lit-html より hyperHTML のほうが楽でいいですね