Menanggalkan API komponen web anda ialah cara terbaik untuk menyampaikan kepada pengguna anda bahawa ciri akan dialih keluar dalam keluaran utama pakej anda yang seterusnya. Jika anda menggunakan Manifes Elemen Tersuai untuk mendokumenkan API komponen anda, ini mungkin lebih rumit daripada yang kelihatan. Komponen web biasanya mempunyai lebih banyak API awam daripada komponen rangka kerja:
Dalam artikel ini, saya akan menunjukkan cara untuk mendokumentasikan penamatan API anda dan menambah ciri gantian tanpa memperkenalkan perubahan pecah.
Salah satu bahagian paling rumit dalam proses penamatan ialah dokumentasi. Untuk sifat, kaedah dan juga komponen anda, ini boleh semudah menambah teg @deprecated pada ulasan JSDoc anda dalam kelas komponen.
/** * @deprecated This component is going away. Use ... instead. */ class MyElement extends HTMLElement { /** @deprecated This property is being removed. Use ... instead. */ myProp; /** @deprecated This method is going away. Use ... instead. */ myMethod() { } }
Pembolehubah CSS, bahagian CSS, slot, acara dan atribut biasanya didokumenkan dalam JSDoc kelas.
Berikut ialah contoh perkara yang anda boleh dokumenkan dalam elemen tersuai JSDoc:
/** * @attr {boolean} disabled - disables the element * @attribute {string} foo - description for foo * * @csspart bar - Styles the bar element in the shadow DOM * * @slot - This is a default/unnamed slot * @slot container - You can put some elements here * * @cssprop --text-color - Controls the color of foo * @cssproperty [--background-color=red] - Controls the background color of bar * * @prop {boolean} prop1 - some description * @property {number} prop2 - some description * * @fires custom-event - some description for custom-event * @fires {MyType} typed-event - some description for typed-event * @event {MyType} typed-custom-event - some description for typed-custom-event * * @summary This is MyElement * * @tag my-element * @tagname my-element */ class MyElement extends HTMLElement {}
Cabarannya ialah anda tidak boleh menggandakan teg JSDoc dan menggunakan teg @deprecated untuk menunjukkan bahawa item ini sudah tidak digunakan lagi. Jika tidak, ia akan ditafsirkan kerana keseluruhan kelas ditamatkan.
/** * @cssprop --text-color - @deprecated I dub thee "deprecated" ❌ */ class MyElement extends HTMLElement {}
Untuk mengatasi perkara ini, saya mencipta alat (custom-elements-manifest-deprecator) yang membolehkan anda menandai item dalam JSDoc anda supaya ia dikemas kini dengan sewajarnya dalam Manifes Unsur Tersuai.
Menggunakan alat ini, anda boleh menggunakan teg alternatif untuk mengenal pasti API yang tidak digunakan lagi. Secara lalai, ia menggunakan teg @deprecated yang dibalut kurungan sebagai pengecam (iaitu yang akan kami gunakan hari ini), tetapi ia boleh disesuaikan dengan apa sahaja yang anda mahukan.
/** * @cssprop --text-color - (@deprecated) I dub thee "deprecated" ? */ class MyElement extends HTMLElement {}
Perkara penting bagi pasukan kami ialah apabila kami akan mengalih keluar atau menukar API, kami cuba memperkenalkan ciri baharu sebelum keluaran utama seterusnya supaya pasukan boleh berhijrah kepadanya lebih awal. Dengan cara itu, jika mereka sentiasa mengikuti perkembangan terkini, mereka boleh meminimumkan kesan peningkatan kepada versi baharu.
Dalam bahagian seterusnya ini, kami akan membincangkan cara memperkenalkan ciri baharu tanpa melanggar API lama anda dan cara ia boleh wujud bersama tanpa bersaing antara satu sama lain. Kami akan mengemas kini beberapa API untuk komponen butang mudah.
Dalam contoh ini saya akan menggunakan Lit, tetapi ciri dan prinsip ini boleh digunakan pada mana-mana persekitaran.
Untuk menyediakan autolengkap dan penerangan yang lebih baik dalam editor kami seperti VS Code dan JetBrains, kami perlu menyediakan nama pembolehubah CSS khusus komponen.
/** * @deprecated This component is going away. Use ... instead. */ class MyElement extends HTMLElement { /** @deprecated This property is being removed. Use ... instead. */ myProp; /** @deprecated This method is going away. Use ... instead. */ myMethod() { } }
Bahagian yang sukar ialah pasukan sudah menggunakan pembolehubah lama, jadi kami memerlukan kedua-duanya untuk berfungsi. Kita boleh melakukan ini dengan memetakan pembolehubah yang tidak digunakan kepada yang baharu dan mengemas kini kod butang kami untuk menggunakan pembolehubah sahaja. Dengan cara itu, jika pengguna menggayakan pembolehubah yang ditamatkan, mereka akan digunakan pada pembolehubah baharu atau pengguna boleh menggunakan nilai pada pembolehubah baharu secara terus.
/** * @attr {boolean} disabled - disables the element * @attribute {string} foo - description for foo * * @csspart bar - Styles the bar element in the shadow DOM * * @slot - This is a default/unnamed slot * @slot container - You can put some elements here * * @cssprop --text-color - Controls the color of foo * @cssproperty [--background-color=red] - Controls the background color of bar * * @prop {boolean} prop1 - some description * @property {number} prop2 - some description * * @fires custom-event - some description for custom-event * @fires {MyType} typed-event - some description for typed-event * @event {MyType} typed-custom-event - some description for typed-custom-event * * @summary This is MyElement * * @tag my-element * @tagname my-element */ class MyElement extends HTMLElement {}
Kini kami boleh mengemas kini maklumat JSDoc kami dengan pembolehubah CSS baharu dan menambah (@tidak digunakan lagi) kepada yang lama dengan perihalan yang dikemas kini.
/** * @cssprop --text-color - @deprecated I dub thee "deprecated" ❌ */ class MyElement extends HTMLElement {}
Seperti pembolehubah CSS kami, kami ingin memberikan nama ruang nama untuk bahagian kami untuk sokongan perkakas yang lebih baik, jadi kami akan menggantikan kawalan dengan kawalan butang. Bahagian CSS agak mudah kerana kita boleh menggunakan berbilang bahagian pada elemen seperti kelas CSS, jadi mari kita gunakan nama bahagian baharu pada elemen itu bersama bahagian yang lain.
/** * @cssprop --text-color - (@deprecated) I dub thee "deprecated" ? */ class MyElement extends HTMLElement {}
Kini kami boleh mengemas kini JSDoc kami dengan bahagian baharu, menghentikan bahagian lama dengan (@tidak digunakan), dan mengemas kini perihalan.
/* old variables */ --bg-color: #ccc; --fg-color: black; /* new variables */ --button-bg-color: #ccc; --button-fg-color: black;
Dengan inisiatif baharu untuk komponen kami menyokong pengantarabangsaan (i18n), kami mengemas kini beberapa API kami agar lebih bermakna dalam bahasa RTL (kanan ke kiri). Satu perkara yang kami mahu lakukan ialah mengemas kini slot kami yang bertujuan untuk memaparkan ikon sebelum teks butang dari kiri ke permulaan tanpa memecahkan pengalaman untuk projek yang sudah menggunakan slot kiri.
Kita boleh melakukan ini dengan meletakkan slot yang tidak digunakan dalam slot baharu. Jika slot baharu tidak digunakan, ia akan "kembali" ke slot lama.
--bg-color: #ccc; --fg-color: black; --button-bg-color: var(--bg-color); --button-fg-color: var(--fg-color); button { background-color: var(--button-bg-color); border: solid 1px var(--button-fg-color); color: var(--button-fg-color); }
Kini kami boleh mengemas kini JSDoc kami dengan slot baharu, menghentikan penggunaan slot lama dengan (@tidak digunakan lagi), dan mengemas kini perihalan.
/** * An example button element. * * @tag my-button * * @cssprop [--bg-color=#ccc] - (@deprecated) (use `--button-bg-color` instead) controls the background color of the button * @cssprop [--fg-color=black] - (@deprecated) (use `--button-fg-color` instead) controls the foreground/text color of the button * @cssprop [--button-bg-color=#ccc] - controls the background color of the button * @cssprop [--button-fg-color=black] - controls the foreground/text color of the button * */
Sebagai contoh kami, kami mengeluarkan acara fokus tersuai, tetapi ia semakin mengelirukan untuk pasukan, jadi kami ingin menambah acara ruang nama (fokus saya). acara adalah agak mudah kerana anda boleh mengeluarkan kedua-dua acara dan pembangun boleh beralih ke acara baharu apabila mereka mendapat peluang.
<button part="control button-control"> <slot></slot> </button>
Kini kami boleh mengemas kini JSDoc kami dengan acara baharu, menghentikan acara lama dengan (@tidak digunakan lagi), dan mengemas kini perihalan.
/** * An example button element. * * @tag my-button * * @csspart control - (@deprecated) (use `button-control` instead) provides a hook to style internal button element * @csspart button-control - provides a hook to style internal button element */
NOTA: Kebanyakan alatan menerima @event dan @fires untuk mendokumentasikan acara. Tidak ada perbezaan di antara mereka.
Kaedah agak mudah untuk ditambah selari antara satu sama lain dan anda boleh menggunakan teg @deprecated standard dalam perihalan kaedah untuk memberitahu bahawa ia telah ditamatkan.
/** * @deprecated This component is going away. Use ... instead. */ class MyElement extends HTMLElement { /** @deprecated This property is being removed. Use ... instead. */ myProp; /** @deprecated This method is going away. Use ... instead. */ myMethod() { } }
Sifat dan atribut boleh didokumenkan dalam JSDoc kelas menggunakan teg @attr/@attribute dan @prop/@property. Jika anda menggunakannya, anda boleh menggunakan teg (@deprecated) untuk menghentikannya dalam Manifes Elemen Tersuai, namun, biasanya lebih baik untuk mendokumenkan harta tersebut secara langsung menggunakan ulasan JSDocnya sendiri. Ini akan membolehkan perkara seperti jenis dan alatan lain mengenal pasti API yang tidak digunakan dengan betul.
Perkara yang menarik ialah kebanyakan penganalisis cukup baik tentang mengaitkan atribut dengan sifat yang ditakrifkan dalam kelas komponen dengan penghias atau konfigurasi lain, jadi jika anda menafikan sifat tersebut, atribut yang berkaitan juga akan ditamatkan.
Dalam komponen demo kami, kami mempunyai atribut disable yang ingin kami kemas kini kepada disable agar lebih sejajar dengan elemen HTML asli.
Perkara pertama yang kami mahu lakukan ialah menafikan harta lama dan menambah harta baharu kami.
/** * @attr {boolean} disabled - disables the element * @attribute {string} foo - description for foo * * @csspart bar - Styles the bar element in the shadow DOM * * @slot - This is a default/unnamed slot * @slot container - You can put some elements here * * @cssprop --text-color - Controls the color of foo * @cssproperty [--background-color=red] - Controls the background color of bar * * @prop {boolean} prop1 - some description * @property {number} prop2 - some description * * @fires custom-event - some description for custom-event * @fires {MyType} typed-event - some description for typed-event * @event {MyType} typed-custom-event - some description for typed-custom-event * * @summary This is MyElement * * @tag my-element * @tagname my-element */ class MyElement extends HTMLElement {}
Sekarang, kami ingin mengelak daripada menyemak kedua-dua sifat setiap kali kami perlu menentukan sama ada komponen itu dilumpuhkan. Untuk memudahkan ini, kita boleh menukar harta yang tidak digunakan kepada pengambil/penetap dan menggunakan harta baharu itu untuk menjadi sumber kebenaran.
/** * @cssprop --text-color - @deprecated I dub thee "deprecated" ❌ */ class MyElement extends HTMLElement {}
Kini, apabila nilai lama dikemas kini, ia akan mengemas kini nilai baharu secara automatik, jadi kami hanya perlu menyemak sifat baharu untuk menentukan sama ada komponen itu dilumpuhkan.
/** * @cssprop --text-color - (@deprecated) I dub thee "deprecated" ? */ class MyElement extends HTMLElement {}
Lihat contoh yang lengkap!
Menukar API boleh menyebabkan komplikasi, tetapi ini tidak bermakna anda perlu berhenti menghasilkan ciri baharu kerana ia mungkin melibatkan perubahan yang melanggar. Memperkenalkan ciri baharu lebih awal dan menafikan ciri lama boleh menjadi satu cara untuk memberikan pengalaman pembangun (DX) yang baik. Ini menyediakan laluan peningkatan progresif dan bukannya memaksa pasukan menunggu dan membuat perubahan besar-besaran sekaligus untuk memanfaatkan ciri baharu.
Atas ialah kandungan terperinci Menamatkan API Komponen Web Anda. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!