Webコンポーネントを使用しない理由


私の最初のポストについては、私は私は論争の無料です:安全なトピックについて書くと思いました:Webコンポーネント.
私はほとんど私の将来の自己のためにこれを書いているので、私は次の時間を誰かになぜ私はWebコンポーネント懐疑的である理由を求めるポイントを持っているSvelte カスタム要素をデフォルトでコンパイルしません.(それはCESにコンパイルすることができます、そして、それは上でその完全な得点によって証明されるように、CESを消費することができます)Custom Elements Everywhere .)
これはWebコンポーネントで行われているハードワークの批評として取り上げられるべきではありません.この投稿でエラーを犯した可能性があります.
Webコンポーネントを使うべきではないと言っています.彼らは有効なユースケースを持っています.私は理由を説明しています.

進歩的強化


これはますます昔ながらのビューかもしれませんが、ウェブサイトはJavaScriptなしで動作するはずです.Webコンポーネントはありません.
これは、カスタムフォーム要素のように本質的にインタラクティブなものに適しています.<cool-datepicker> ), しかし、それはあなたのNAVバーの罰金ではない.または単純なものを考慮する<twitter-share> URLを構築するためのすべてのロジックをカプセル化する要素.私だってbuild it in Svelte そして、以下のようなHTMLで書かれたサーバを生成します.
<a target="_blank" noreferrer href="..." class="svelte-1jnfxx">
  Tweet this
</a>
つまり、ボッグスタンダード<a> 要素、すべてのアクセス可能な栄光で.
JavaScriptが有効になって、それは徐々に強化-新しいタブを開くよりもむしろ、それは小さなポップアップウィンドウを開きます.しかし、それはまだうまく動作します.
対照的に、WebコンポーネントHTMLはこのようになります.
<twitter-share text="..." url="..." via="..."/>
...JSが無効になっているか、どうにか壊れているか、ユーザが古いブラウザ上にある場合は役に立ちません.
The class="svelte-1jnfxx" シャドウDOMなしでカプセル化されたスタイルを有効にするものです.これは私の次のポイントに私をもたらします.

2 . CSS、err ...js


スタイルカプセル化のためにシャドウDOMを使用する場合は、あなたのCSSを<style> 要素.唯一の実用的な方法は、少なくともFOCを避けたい場合は、カスタム要素を定義するJavaScriptモジュールの文字列をCSSにすることです.
これは' JavaScriptを以下のように要約することができます与えられているパフォーマンスのアドバイスに逆らってください'.特にCSSを入れていないので、JSコミュニティのCSSは批判されています.css ファイルは、まだここにあります.
将来的には、我々は使用できるかもしれませんCSS Modules 並んでConstructable Stylesheets この問題を解決する.そして、我々は使用できるかもしれません::theme and ::part Shadow DOMの中のスタイルに.しかし、これらの問題は無料です.

プラットホーム疲労



リッチハリス
リッチェハリス

これは私たちのペットのおむつです-私たちは何年もの間、このようなものを行ってきたが、現在の*を追いつくためには、我々はすべてのこれらの新機能を持つガイルには、プラットフォームをする必要があります既存のブラウザの周りの堀を深める必要があります
午後17時55分- 2019年7月19日
0
3
執筆時には61000のオープン問題がありますhttps://crbug.com , クロムバグトラッカーは、近代的なWebブラウザを構築するの巨大な複雑さを反映しています.
我々はプラットフォームに新しい機能を追加するたびに、我々はその複雑さを増加させる-バグのための新しい表面積を作成し、それが少なくなる可能性が少ないクロムに新しい競合他社が出てくる可能性があります.
また、これらの新機能を学ぶことが奨励されている開発者にとっても複雑さを生んでいます(その一部はHTMLインポートやオリジナルカスタム要素仕様のように、Googleの外部でキャッチして、再び取り外されることはありません).

ポリフィル


あなたがすべてのブラウザーをサポートしたいならば、あなたはPolyFillsを使う必要があるのを助けません.それは本当にその文学を助けていないConstructable Stylesheets , Googler(ハイジェイソン!)によって書かれます.彼らはクロームのみの機能であることに言及しないpull request ). The three spec editors すべてのgooglersです.WebKitseem to have some doubts デザインのいくつかの側面について.

合成


コンポーネントがそのスロットされた内容がレンダリングされるかどうかを制御することができるのは便利です.我々が我々を使いたかったと仮定してください <html-include> element ネットワークから表示されるドキュメントを表示するには、次の手順に従います.
<p>Toggle the section for more info:</p>
<toggled-section>
  <html-include src="./more-info.html"/>
</toggled-section>
驚き!あなたがまだ開いているセクションをトグルしなかったとしてもmore-info.html , に沿って任意の画像や他のリソースにリンクします.
スロット付きコンテンツがカスタム要素に熱心にレンダリングされるためです.それはあなたが怠惰にレンダリングするためにスロット付きコンテンツを望むほとんどの時間が判明した.Svelte v 2はWeb標準と整列するために熱心なモデルを採用し、フラストレーションの主な原因であることがわかった.Svelte V 3では、カスタム要素の構成モデルを放棄し、決して振り返った.
残念ながら、これはDOMの基本的な特徴です.……

小道具と属性の混同


小道具と属性は基本的に同じことですね.
const button = document.createElement('button');

button.hasAttribute('disabled'); // false
button.disabled = true;
button.hasAttribute('disabled'); // true

button.removeAttribute('disabled');
button.disabled; // false
つまり、ほとんど
typeof button.disabled; // 'boolean'
typeof button.getAttribute('disabled'); // 'object'

button.disabled = true;
typeof button.getAttribute('disabled'); // 'string'
そして、マッチしない名前があります.
div = document.createElement('div');

div.setAttribute('class', 'one');
div.className; // 'one'

div.className = 'two';
div.getAttribute('class'); // 'two'
...そして、まったく対応していないようなもの
input = document.createElement('input');

input.getAttribute('value'); // null
input.value = 'one';
input.getAttribute('value'); // null

input.setAttribute('value', 'two');
input.value; // 'one'
しかし、私たちはそれらの癖で暮らすことができます、なぜならば、若干のものはストリング形式(HTML)とDOMの間で翻訳で失われます.彼らの数は限られています、そして、彼らは文書化されます、それで、少なくとも、あなたは十分な時間と忍耐を与えられるそれらについて学ぶことができます.
Webコンポーネントが変更されます.属性と小道具の関係についての保証はもはやないのですが、Webコンポーネントの作者としては(おそらく?両方をサポートすることになっている.つまり、このようなことがわかるでしょう.
class MyThing extends HTMLElement {
  static get observedAttributes() {
    return ['foo', 'bar', 'baz'];
  }

  get foo() {
    return this.getAttribute('foo');
  }

  set foo(value) {
    this.setAttribute('foo', value);
  }

  get bar() {
    return this.getAttribute('bar');
  }

  set bar(value) {
    this.setAttribute('bar', value);
  }

  get baz() {
    return this.hasAttribute('baz');
  }

  set baz(value) {
    if (value) {
      this.setAttribute('baz', '');
    } else {
      this.removeAttribute('baz');
    }
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'foo') {
      // ...
    }

    if (name === 'bar') {
      // ...
    }

    if (name === 'baz') {
      // ...
    }
  }
}
時には物事は別の方法で行く-attributeChangedCallback 代わりにプロパティアクセサーを呼び出す.いずれにせよ、人間工学は悲惨です.
対照的に、フレームワークは、データをコンポーネントに渡す単純で明白な方法を持っています.

リークデザイン


この点は少しより薄いですが、それは私を怒らせるattributeChangedCallback は要素インスタンスのメソッドです.文字通りこれを行うことができます.
const element = document.querySelector('my-thing');
element.attributeChangedCallback('w', 't', 'f');
属性は変更されませんでした、しかし、それはそれのように振る舞うでしょう.もちろん、JavaScriptは常にいたずらの機会をたっぷり提供してきました.しかし、実装の詳細を見てみると、デザインが全く正しくないと私たちに伝えているように感じます.

8 . DOMは悪い


OK、我々はすでにDOMが悪いことを確立しました.しかし、それは対話的なアプリケーションを構築するための厄介なインターフェイスは何を過小評価するのは難しい.
数ヶ月後、私は記事を書いたWrite less code , Sveletがあなたが反応とVueのようなフレームワークより効率的に構成要素を構築するのを許す方法を説明することを目的とします.しかし、私はそれをDOMと比較しませんでした.すべきだ.
要約するには、ここでは簡単です<Adder a={1} b={2}/> コンポーネント
<script>
  export let a;
  export let b;
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {a + b}</p>
それは全部です.さて、Webコンポーネントと同じものを作りましょう.
class Adder extends HTMLElement {
  constructor() {
    super();

    this.attachShadow({ mode: 'open' });

    this.shadowRoot.innerHTML = `
      <input type="number">
      <input type="number">
      <p></p>
    `;

    this.inputs = this.shadowRoot.querySelectorAll('input');
    this.p = this.shadowRoot.querySelector('p');

    this.update();

    this.inputs[0].addEventListener('input', e => {
      this.a = +e.target.value;
    });

    this.inputs[1].addEventListener('input', e => {
      this.b = +e.target.value;
    });
  }

  static get observedAttributes() {
    return ['a', 'b'];
  }

  get a() {
    return +this.getAttribute('a');
  }

  set a(value) {
    this.setAttribute('a', value);
  }

  get b() {
    return +this.getAttribute('b');
  }

  set b(value) {
    this.setAttribute('b', value);
  }

  attributeChangedCallback() {
    this.update();
  }

  update() {
    this.inputs[0].value = this.a;
    this.inputs[1].value = this.b;

    this.p.textContent = `${this.a} + ${this.b} = ${this.a + this.b}`;
  }
}

customElements.define('my-adder', Adder);
うん.
あなたが変わるならばa and b 同じ瞬間に、それは2つの別々の最新版に終わります.フレームワークは一般的にこの問題に苦しむことはありません.

9 .グローバル名前空間


我々はあまりにも、この1つに住む必要はありません単一の共有名前空間を持つ危険性は、しばらくの間よく理解されていると言います.

10 .すべて問題解決


すべての最大の欲求不満は、我々はすでに本当に良いコンポーネントモデルを持っていることです.我々はまだ学んでいるが、基本的な問題-コンポーネント指向のファッションでDOMを操作することによっていくつかの状態と同期してビューを維持-長年解決されています.
しかし、我々はちょうど我々がすでにユーザーランドですることができるものと同等にウェブ構成要素を持ってくるために、新しい特徴をプラットホームに加えています.
有限資源を与えられて、1つの仕事に費やされる時間は、もう一つの仕事に費やされない時間を意味します.大部分の無関心な開発者人口にもかかわらず、かなりのエネルギーはウェブ構成要素に費やされました.そのエネルギーが他の場所で使われたならば、ウェブは何を成し遂げたでしょうか?