Linten von Salesforce Lightning Web Components (LWC)
Erstellen Sie Schritt für Schritt eine Komponentenkonfiguration, indem Sie Salesforce Lightning Web Components als ein Beispiel verwenden
Salesforce Lightning Web Component (LWC)-Vorlagen sind HTML-Dateien, die aus benutzerdefinierten Elementen bestehen: Salesforce-Basis-Komponenten wie <lightning-button> und <lightning-icon> sowie die Komponenten, die Sie selbst im c--Namespace erstellen, wie <c-my-image>. Axe DevTools Linter überprüft benutzerdefinierte Elemente, sobald Sie ihm mitteilen, was diese Elemente rendern, unter Verwendung der global-components-Konfigurationsoption.
Dieser Artikel entwickelt eine LWC-Konfiguration von Grund auf. LWC eignet sich gut als Beispiel, da es alle Teile der Abbildungssyntax umfasst, einschließlich Komponenten, die kein eigenes Element rendern. Die Methode kann auf jede Komponentenbibliothek angewendet werden: Beschreiben Sie, was jede Komponente rendert, überprüfen Sie diese Beschreibung mit einer Testdatei und korrigieren Sie die Abbildung, wo immer es Diskrepanzen gibt.
Für eine Einführung in die Abbildung benutzerdefinierter Komponenten siehe Benutzerdefinierte Komponenten linten. Für das vollständige Syntax-Referenzschema siehe Konfigurieren von Axe DevTools Linter.
Bevor Sie beginnen
Fügen Sie eine axe-linter.yml-Datei zum Stammverzeichnis Ihres Projekts hinzu. Jedes unten stehende Beispiel geht in diese Datei. Wenn Sie das REST-Endpunkt anstelle einer Editor-Erweiterung verwenden, geht dieselbe Konfiguration in das config-Objekt der Anfrage, wie in Linten von benutzerdefinierten Komponenten mit dem Axe DevTools Linter REST-Endpunkt gezeigt.
Eine Abbildung beschreibt, was der Browser empfängt
Dies ist die Idee, die jede andere Entscheidung einfach macht: Eine Abbildung beschreibt das Element, das Ihre Komponente rendert, nicht den Tag, den Sie im Template schreiben.
<lightning-button label="Save"> rendert einen button, dessen Textinhalt „Speichern“ ist. Als Abbildung sieht das so aus:
global-components:
lightning-button:
element: button
attributes:
- label: <text>Der spezielle <text>-Wert gibt an, dass das label-Attribut zum Textinhalt des Elements wird, was einem Knopf seinen zugänglichen Namen gibt. Mit dieser Abbildung meldet Axe DevTools Linter einen button-name-Verstoß für <lightning-button> ohne label, genau so, wie es für ein leeres <button> der Fall wäre.
Schritt 1: Abbilden der Komponenten, die ein Element rendern
Beginnen Sie mit Komponenten, die sich sauber auf ein einziges nativer Element abbilden lassen, und nehmen Sie nur die Attribute auf, die Barrierefreiheitsinformationen enthalten.
global-components:
# Salesforce base components
lightning-button:
element: button
attributes:
- label: <text>
lightning-icon:
element: img
attributes:
- alternative-text: alt
# Components you author yourself
c-my-image:
element: img
attributes:
- alternative-text: altKomponentennamen sind groß-/klein-schreibungsempfindlich und entsprechen dem Tag, wie Sie es im Template schreiben, daher werden die kebab-case-Namen von LWC unverändert verwendet.
Für die anderen speziellen Werte (aria-*, um ARIA-Attribute durchzureichen, <element>, um ein Attribut das emittierte Element wählen zu lassen, und default, um einen Wert anzugeben, den die Komponente immer rendert) siehe die Anleitung in Linten von benutzerdefinierten Komponenten mit der Axe Accessibility Linter-Erweiterung für VS Code oder dem JetBrains-Plugin.
Schritt 2: Deklarieren der Wrapper, die nichts rendern
LWC verwendet <template> für ein Komponentes Wurzelelement und erneut für Iterationen und Bedingungen:
<template>
<ul>
<template for:each={items} for:item="item">
<li key={item.id}>{item.name}</li>
</template>
</ul>
</template>In HTML sind die Inhalte eines <template>-Elements inert: Der Browser rendert sie nicht, und unterstützende Technologien können nicht darauf zugreifen. Axe DevTools Linter bewertet das Markup, das ein Benutzer tatsächlich erhält, weshalb es keine Inhalte innerhalb eines <template> meldet. LWC verwendet denselben Tag-Namen für eine Anweisung zur Kompilierungszeit, die überhaupt kein Element erzeugt, weshalb dem Linter mitgeteilt werden muss, was aus diesen Wrappern wird. Das obige Markup erreicht den Browser so:
<ul>
<li>…</li>
<li>…</li>
</ul>Das Deklarieren von template in Ihrer Konfiguration ermöglicht es dem Linter, durch diese Wrapper zu den innenliegenden Markups zu gelangen. Da eine Abbildung ein Element nennen muss, und da eine Abbildung überall dort gilt, wo das Tag erscheint, ist das gewählte Element wichtig. Das Durcharbeiten zweier Optionen mit der obigen Liste zeigt, warum.
Versuch eines generischen Containers
Ein div ist der natürliche erste Versuch, da ein Wrapper wie ein generischer Container klingt:
global-components:
template: divAxe DevTools Linter bewertet nun die Liste, als hätten Sie den <template> als div geschrieben:
<ul>
<div>
<li>…</li>
</div>
</ul>Und Es meldet einen Verstoß auf der <ul>-Zeile:
list: <ul> and <ol> must only directly contain <li>, <script> or <template> elementsDer Bericht ist korrekt über das Markup, das ihm gegeben wurde, aber dieses Markup ist nicht das, was der Browser erhält. LWC entfernt den Wrapper, sodass die gerenderte Liste direkt Listenelemente enthält und vollkommen gültig ist. Der Verstoß stammt von dem Ersatz-Element, nicht von Ihrem Template.
Das gerenderte Verhältnis anpassen
Jetzt mappen Sie template auf das Element, das der Browser tatsächlich innerhalb der Liste findet:
global-components:
template: liDer Linter bewertet die gleiche Liste so:
<ul>
<li>
<li>…</li>
</li>
</ul>Kein list-Verstoß wird gemeldet, da der <ul> direkt ein li enthält, was eines der Elemente ist, die die obige Regelmeldung zulässt, und es ist auch das Verhältnis, das der Browser erhält. Der doppelte li existiert nur in der Ansicht des Linters Ihrer Datei: Er steht für einen Wrapper, der nichts rendert, und Sie schreiben ihn nie in ein Template.
Das Weglassen von template aus Ihrer Konfiguration vermeidet auch den Verstoß, aber dann wird nichts in Ihren Templates überhaupt bewertet, was das Problem ist, das Schritt 2 zu lösen versucht hat.
Beide Auswahlmöglichkeiten überprüfen den Inhalt im Inneren
Das Ersatz-Element beeinflusst nur, wie der Wrapper selbst dem Linter erscheint. Das Markup innerhalb wird in jedem Fall bewertet. Fügen Sie dasselbe Liste ein Bild ohne Alternativtext hinzu:
<template>
<ul>
<template for:each={items} for:item="item">
<li key={item.id}><img src={item.url}></li>
</template>
</ul>
</template>Sowohl template: div als auch template: li melden den fehlenden Alternativtext beim Bild:
image-alt: Images must have alternative textMit template: div erhalten Sie dieses Ergebnis plus den überflüssigen list-Verstoß, was den praktischen Unterschied zwischen den beiden darstellt. Da die Iteration über Listenelemente die häufigste Verwendung von <template> ist, entspricht das Mapping auf li am häufigsten dem gerenderten Ergebnis, und es wird als Startpunkt empfohlen.
Drei Regeln überprüfen, ob ein Behälter die richtige Art von direkten Kind enthält: list für <ul> und <ol>, definition-list für <dl>, und summary-name für <details>. Wo ein <template> direkt innerhalb eines dieser vier Behälter sitzt, nimmt Ihr Ersatz-Element seinen Platz ein, sodass diese drei Regeln möglicherweise nicht das melden, was sie für das entsprechende plain HTML tun würden. Keine andere Regel ist betroffen, und der Inhalt innerhalb des Templates wird weiterhin vollständig geprüft.
Schritt 3: Überprüfen Sie Ihre Konfiguration
Gehen Sie nicht davon aus, dass eine Abbildung so funktioniert, wie Sie es beabsichtigt haben. Der zuverlässigste Test ist, das gleiche Markup zweimal zu schreiben, einmal mit Ihren Komponenten und einmal als das schlichte HTML, das Sie erwarten, dass diese Komponenten rendern, und bestätigen, dass beide die gleichen Ergebnisse erzielen.
Erstellen Sie eine kleine Testdatei, scratch.html, irgendwo im Projekt, das Axe DevTools Linter prüft:
<template>
<c-my-image src="cat.jpg"></c-my-image>
<lightning-button></lightning-button>
</template>Dann erstellen Sie ihr schlichtes HTML-Pendant, scratch-expected.html, mit dem Markup, das Sie erwarten, dass diese Komponenten rendern:
<img src="cat.jpg">
<button></button>Mit den Abbildungen aus den Schritten 1 und 2 melden beide Dateien die gleichen zwei Verstöße: image-alt für das Bild ohne Alternativtext und button-name für den Knopf ohne zugänglichen Namen. Übereinstimmende Ergebnisse bedeuten, dass die Abbildungen Ihre Komponenten korrekt beschreiben. Ein Verstoß in einer Datei, aber nicht in der anderen, weist eher auf die Konfiguration hin als auf Ihr Markup.
Dieses Paar zeigt auch, warum es sich lohnt, den Test durchzuführen. Ohne die template-Abbildung aus Schritt 2 meldet scratch.html überhaupt nichts, während scratch-expected.html beide Verstöße meldet, und dieser Unterschied weist darauf hin, dass in der Konfiguration etwas fehlt.
Es gibt drei bequeme Wege, um die Ergebnisse zu sehen:
- Öffnen Sie in VS Code oder einer JetBrains IDE die Datei und lesen Sie die hervorgehobenen Fehler, wie in Linten von benutzerdefinierten Komponenten mit der Axe Accessibility Linter-Erweiterung für VS Code oder dem JetBrains-Plugin beschrieben.
- Mit dem Axe DevTools Linter Connector führen Sie es in einem Befehl für beide Dateien aus.
- Mit dem REST-Endpunkt veröffentlichen Sie den Inhalt jeder Datei zusammen mit Ihrer Konfiguration im Objekt
config. Siehe Linten von benutzerdefinierten Komponenten mit dem Axe DevTools Linter REST-Endpunkt.
Das Hinzufügen des Komponentennamens zu jedem Ergebnis erleichtert das Debuggen größerer Konfigurationen erheblich, da es zeigt, welche Zuordnung eine Verletzung verursacht hat. Siehe Analyse von Verletzungen der benutzerdefinierten Komponenten.
Entscheiden, was eine Zuordnung erfordern sollte
Einige Komponenten rendern je nach Verwendung unterschiedliches Markup, und deren Zuordnung ist eine Richtlinienentscheidung und keine einfache Übersetzung. <lightning-icon> ist ein gutes Beispiel: ein Symbol ohne alternative-text ist dekorativ, während ein Symbol mit alternative-text eine Bedeutung vermittelt.
Die Zuordnung von <lightning-icon> zu img bedeutet, dass der Linter jedes Symbol auffordert, seinen Alternativtext anzugeben. Ein ausdrücklich leerer Wert erfüllt diese Anforderung:
<!-- Reported: an image with no alternative text -->
<lightning-icon icon-name="utility:check"></lightning-icon>
<!-- Not reported: explicitly decorative -->
<lightning-icon icon-name="utility:check" alternative-text=""></lightning-icon>Das ist eine nützliche Konvention, da sie die Absicht jedes Symbols im Template sichtbar macht, anstatt sie durch Auslassung impliziert zu lassen. Wenn Sie es vorziehen, diese nicht zu übernehmen, lassen Sie <lightning-icon> aus Ihrer Konfiguration weg, und der Linter wird es nicht auswerten.
Wenn eine Komponente für ein Attribut immer denselben Wert rendert, wie zum Beispiel einen festen role, verwenden Sie default, um diesen Wert festzuhalten. Ein default tritt nur in Kraft, wenn der Wert nicht leer ist, und ein default kann ein Attribut setzen, aber keinen <text>-Inhalt bereitstellen. Siehe Standardattribute.
Ordnen Sie nur die Attribute zu, die Barrierefreiheitsinformationen enthalten, und überprüfen Sie, was jede Komponente rendert, bevor Sie sie zuordnen. Die Beispiele in diesem Artikel folgen dem Markup, das die Salesforce-Basiskomponenten erzeugen, aber Ihre eigenen Komponenten und jede Komponente, die Sie umwickeln, benötigen dieselbe Überprüfung.
Anwendung auf Ihre eigenen Komponenten
Die obigen Schritte lassen sich auf jede Komponentenbibliothek verallgemeinern:
- Liste der Komponenten, die ein interaktives oder bedeutungsvolles Element rendern, wie Schaltflächen, Links, Bilder, Formularsteuerungen und Überschriften. Diese bieten den größten Nutzen bei der geringsten Konfiguration.
- Notieren Sie sich für jede, was sie rendert und welche Attribute Barrierefreiheitsinformationen enthalten, und ordnen Sie dann nur diese Attribute zu.
- Deklarieren Sie Wrapper, die nichts Eigenes rendern und wählen Sie ein Ersatzelement, das die Beziehung, die der Browser sieht, bewahrt.
- Verifizieren Sie jede Zuordnung gegenüber ihrem HTML-Äquivalent, bevor Sie sich darauf verlassen.
- Überarbeiten Sie die Konfiguration, wenn sich Ihre Komponenten ändern. Eine Zuordnung spiegelt nur wider, wie sich eine Komponente an dem Tag verhielt, an dem die Zuordnung geschrieben wurde.
Wenn Ihre Bibliothek eine der Bibliotheken ist, die Axe DevTools Linter bereits kennt, können Sie die meisten dieser Arbeiten überspringen. Siehe Vorkonfigurierte Komponentenbibliotheken.
Siehe auch
- Linter für benutzerdefinierte Komponenten
- Linter für benutzerdefinierte Komponenten mit der Axe Accessibility Linter-Erweiterung für VS Code oder dem JetBrains-Plugin
- Linter für benutzerdefinierte Komponenten mit dem Axe DevTools Linter REST-Endpunkt
- Konfigurieren des Axe DevTools Linters
- Vorkonfigurierte Komponentenbibliotheken
