◆ IE 対応は環境作るだけで大変すぎる
◆ Chrome だけなら楽
◆ IE 対応なら変に新しい機能いれようとせず素直に jQuery してたほうが結果的に楽そう

前の記事の続きです
とりあえず IE で動きはしたものの 面倒も多くてうまく動かないことが多くて大変でした

polymer-cli

動くことはできたものの polymer-cli は他の汎用的なバンドラーに比べて制限も多く使いづらいです

ビルドのフォルダ周り

まずはフォルダ関係です

- build
- src
- ...
- node_modules
- package.json

という構造で src にソースコードを入れて build に結果を入れたいのですが まず出力先を選べません

さらに src フォルダでビルドした場合に root を指定しないとカレントフォルダの src が root になり それより上の node_modules は見てくれません
src の中に node_modules はないので依存モジュールを見つけられずエラーです

root を package.json があるフォルダにした場合は entrypoint に src/index.js のように指定すればビルドできます
しかし build の中に src フォルダがついてきます

あと entrypoint から到達不可能な html なども src の中にあれば全部コピーされます
動的 HTMLImports の対応なのでしょうか

babel を設定できない

また parcel などと違い babel を設定できないようです
.babelrc を使えるようにするという issue もあったのですが結局対応しない方針みたいでした
自由に設定できると競合するケースがあるから みたいなことが書いてました

そのせいでプラグインを入れられないので新しい機能は使えません
今だと lit-element の例をコピペしたら入っていたクラスの static プロパティの定義部分で plugin が必要ってエラーでした

自分でプラグインを入れられないならすごく使い勝手が悪いです

watch がない

serve と build はあるのに watch がないです
serve だと内部でどこかの一時フォルダに出力してるみたいでファイルを更新したら自動でビルドしてくれたものを polymer-cli 組み込みのサーバ以外でホストできません
静的ファイル以外のサーバ機能と組み合わせたいときに不便です

1 ファイルにまとめられる

parcel みたいに html をバンドルしてビルドしても html と js と css のように別れてくれればよいのですが 全部が html に詰め込まれます
html だと devtools でデバッグし辛いのですよね

js ファイルを entrypoint にすることもできますが バンドルしても module を amd に変換しないと最後に export があるので構文エラーです
変換したら amd の define 関数がないと言われてしまいます
html を entrypoint にすれば html に define を定義する script タグが追加されるのに js を entrypoint にすると そういうことをしてくれないようでエラーです

他にも html を entrypoint にしたらいろいろ書き換えてくれるので js を entrypoint にするのは難しそうです

書き換えられる例は

    <script>if (!window.customElements) {
document.write('<!--');
}</script>
<script type="text/javascript" src="../node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<!--! do not remove -->

のように es5-adapter の script タグが追加され 必要な環境でのみロードされるようになってます

またそれより前に polyfill のようなものがいろいろ追加されています
minify 済みなので何してるかがよくわかってません

ただ es5-adapter と webcomponentsjs は別にロードしてるので特にいらなそうなので 何してるのか気になるところです

これじゃないと困るところ

polymer-cli のメリットは http2 とか service worker に対応していて 他のバンドラーみたいにまとめるだけじゃなくて module ごと別ファイルのままにもできるところです
service worker や push manifest のコードも出力したりできますし

逆にいえばそういうことしないなら polymer-cli の必要はなさそうです

parcel

lit-element (WebComponents) を使うだけで polymer 固有の機能を使うわけでもないので いつもの parcel でいいかと parcel にしてみました

package.json に browserslist で chrome 最新版と IE11 を指定するだけ
polymer-cli で追加された es5-adapter は必要ですが追加してくれないので 手動で HTML に追加しておきます

これで build するだけ と思ったのですが IE11 は動きませんでした

parcel は node_modules 以下のモジュールのコードは ES5 に変換してくれません
インポート・エクスポートの変換のみです

ドキュメントをみても
https://parceljs.org/transforms.html

.babelrcのような設定ファイルは、デフォルトではサードパーティのnode_modulesに対しては適用されません。しかしながら、モジュールのディレクトリに対してシンボリックリンクが張られていて(いくつかの monorepo 規則では一般的)、モジュールのpackage.jsonがsourceのフィールドセットを持つ場合には、モジュールに書かれている設定が尊重されます。以下はsourceフィールドでサポートされている値です。

babel の設定などはサードパーティの node_modules に適用されないと書いています
module 側の package.json に source があればその設定が尊重されるらしいですが 結局サードパーティのモジュール依存です
parcel は速くて設定不要が売りですけど webpack だとやってくれるようなことをやらずに飛ばすから速いと考えると 良いのか悪いのか微妙ですね
結局 parcel じゃできないことがあって webpack になるんですから

webpack

そういうわけで結局 webpack
parcel とか楽なツールが進化して webpack は使わずに済んだらいいなーと これまで使ってなかったのですがとうとう使うことになりました

設定ファイルは面倒ですが 細かなところもカスタマイズできるのは利点ではありますね

ここでもいろいろトラブルはありましたが 一応ビルドまでは成功しました
トラブルはこういう感じ

@babel/preset-env が見つからないと言われる
▶ 今のバージョンだと .babelrc があるとダメ
  消せば動く

クラス構文は new 演算子必須なのに apply で呼び出したせいでエラーになる
▶ そもそもクラス構文が存在するのがダメ
  module.rules の .js にマッチするところで node_modules を exclude しない
  exclude すると parcel と同じく node_modules が変換されないので ES5 にならない

これで Chrome が動いたのですが IE11 はなぜか stackoverflow して動きません

スタック領域が不足しています。
webcomponents-bundle.js (78,288)

とエラーです
エラー箇所は webcomponents の polyfill ですが これだけロードしてもエラーは起きず 自分のアプリケーション部分の JavaScript を入れるとエラーです
webpack で作ったアプリケーション部分に問題あるとは思うのですが 調査しづらい IE の devtools でできることもほぼないですし webpack の mode を development と production で切り替えてみても変わらずでした
polyfill がいっぱいだし本当に IE のスペックじゃ無理なのか ライブラリにバグがあるのかわかりませんが これはもうどうにもできそうにないので諦めました

IE 対応のコスト

というか なぜ環境作るだけに 1 日以上も苦労しないといけないのでしょうか
時間が経つほど IE との機能差は増える一方なので 今では IE 対応するのがここまで面倒なんですね

ここまで複雑な構成になってくると IE だけが何かおかしかったり 動かない時はどうしようもない気がしますし 調査するのも一苦労です
そもそも環境作るだけで何日かかるのってレベル

ネットで IE 対応するなら倍くらい請求したいとかいうのを見かけることがありますけど 実際に作業時間が倍以上かかると思います
Chrome だけならこの記事で書いたこと何もせずただ CDN でライブラリロードするだけでいいわけですからね
ビルドもバンドルもいらないってだけでかなり楽になります

こんなに苦労する上に 今後も何か新しく追加のたびに変なバグに出会ったりする可能性もあるとなると IE の対応が必要なら jQuery で昔ながらの作りにしたほうがいいかもしれません
作るときの面倒さはありますが 作り始めるための環境作りに迷うこともなく なにか起きても自力で十分調査できるほうがマシとも言えます
それにフレームワークがないと無理ってレベルの大規模でもないならたぶんそっちのほうが早いです
どっちにしたとしても Chrome や Firefox だけと比べると 2 倍や 3 倍の時間は普通にかかりそうです


ところで 久々に IE 起動したので適当にウェブサービスを開いてみたら IE は対応してませんってエラーが出るところが思いの外 多かったです
なんだかんだサポートしてるものだと思ってましたが 意外とサポート切るのが進んでるようですね
特に海外のサービスで大手ってほどでもないツール系はほとんどダメでした
知ってるツール的に用途が開発者向けぽいのが多めだったのも関係ありそうですけど

そういえば 動かなくて Issues とか探してると 解決策がターゲットを最新 Chrome のみにするとか ES5 は対応させないっていうのばかりで それが解決策として closed みたいのもありました

それに比べると日本は未だに IE もサポートしてるところ多い印象です
前にも書きましたが サポートしてしまうとユーザは使い続けますからね
サポートしてくれる以上やめる理由がないです
遅いとか重いでやめるならとっくにやめてます
未だに使い続けるような人からすれば 「使えなくなった」 が初めてやめようとする理由です
サポート続けてるといつまで経ってもシェアが下がらないのでどんどん非対応なサービスが増えてほしいものです
というか早く Chromium 版 Edge をリリースして公式に IE は完全サポート停止にしてほしいものです