Статический анализ компонентов — это метод проверки корректности семантики и доступности интерфейсов на этапе разработки без выполнения кода в браузере. Анализ осуществляется на основе структуры DOM, ролей ARIA и их разрешённых атрибутов.
Библиотека aria-query предоставляет набор структурированных данных о ролях, состояниях и свойствах ARIA, которые могут использоваться инструментами анализа для выявления нарушений стандартов доступности.
Основная ценность такого подхода заключается в том, что ошибки обнаруживаются ещё до запуска приложения. Это снижает вероятность появления недоступных интерфейсов и упрощает поддержку стандартов WAI-ARIA.
Библиотека содержит таблицы соответствий между:
Эти данные используются инструментами:
Фактически библиотека представляет собой машиночитаемую базу знаний спецификации ARIA.
Основные экспортируемые структуры:
| Экспорт | Назначение |
|---|---|
roles |
список всех ролей ARIA |
aria |
список всех ARIA-атрибутов |
elementRoles |
соответствие HTML-элементов ролям |
roleElements |
обратное соответствие ролей элементам |
Эти структуры позволяют анализировать семантику компонентов без выполнения кода.
Одной из базовых задач статического анализа является проверка корректности назначения ролей.
Каждый HTML-элемент имеет:
Например, элемент <button> уже обладает ролью
button. Попытка назначить ему несовместимую роль может
нарушить семантику.
Пример извлечения данных о роли:
import { roles } from "aria-query";
const buttonRole = roles.get("button");
console.log(buttonRole);
Объект роли содержит:
Такие данные позволяют линтерам выявлять ошибки вроде:
<button role="heading">
Роль heading не предназначена для элемента
button, поэтому анализатор может зафиксировать
нарушение.
Каждая роль ARIA поддерживает строго определённый набор свойств. Использование атрибутов вне допустимого набора является ошибкой.
Пример некорректного кода:
<div role="button" aria-level="2"></div>
Атрибут aria-level используется только для ролей
заголовков.
С помощью aria-query можно определить допустимость
атрибута.
import { roles } from "aria-query";
const role = roles.get("button");
console.log(role.props);
Поле props содержит список поддерживаемых свойств:
aria-expanded
aria-pressed
aria-disabled
...
Если анализатор обнаруживает атрибут вне этого списка, фиксируется ошибка доступности.
Некоторые роли требуют наличия обязательных ARIA-атрибутов.
Например:
checkbox требует aria-checkedslider требует aria-valuemin,
aria-valuemax, aria-valuenowИнформация о таких требованиях содержится в поле
requiredProps.
import { roles } from "aria-query";
const checkboxRole = roles.get("checkbox");
console.log(checkboxRole.requiredProps);
Результат:
{
"aria-checked": null
}
Статический анализ может выявлять ситуации:
<div role="checkbox"></div>
Отсутствие aria-checked означает неполную реализацию
роли.
Библиотека содержит карту elementRoles, описывающую
какие роли допустимы для конкретных HTML-элементов.
Пример получения ролей для элемента:
import { elementRoles } from "aria-query";
for (const [element, roles] of elementRoles) {
console.log(element, roles);
}
Элемент описывается объектом:
{
name: "button"
}
Связанные роли:
Set { "button" }
Такая информация позволяет проверять:
Одной из типичных проблем является дублирование нативной семантики.
Пример:
<button role="button">Save</button>
Назначение роли button избыточно, поскольку она уже
присутствует по умолчанию.
Использование aria-query позволяет определить, что:
<button> → implicit role: button
Следовательно, линтер может предложить удалить явное указание роли.
Статический анализ особенно важен для компонентов React, поскольку JSX скрывает итоговую структуру DOM.
Типичный процесс анализа включает несколько этапов:
aria-queryПример анализа JSX-элемента:
<div role="slider" aria-valuenow="50"></div>
Анализатор выполняет проверки:
sliderdivПри отсутствии aria-valuemin или
aria-valuemax фиксируется ошибка.
Некоторые роли допустимы только внутри определённых контейнеров.
Примеры:
menuitem должен находиться внутри
menulistitem — внутри listoption — внутри listboxИнформация о таких ограничениях содержится в свойствах роли:
requiredContextRole
requiredOwnedElements
Пример проверки:
const menuItem = roles.get("menuitem");
console.log(menuItem.requiredContextRole);
Результат:
["menu", "menubar"]
Анализатор может обнаружить ошибку:
<div role="menuitem"></div>
Такой элемент не имеет родительского menu.
ARIA-роли могут поддерживать различные состояния:
aria-selectedaria-expandedaria-pressedaria-currentСписок допустимых состояний также определяется через
props.
Например:
const tabRole = roles.get("tab");
console.log(tabRole.props);
Результат включает:
aria-selected
aria-expanded
Если компонент использует неподдерживаемое состояние, это фиксируется как ошибка.
Некоторые ARIA-атрибуты принимают ограниченный набор значений.
Например:
aria-checked = true | false | mixed
Информация о типе значения хранится в таблице aria.
Пример:
import { aria } from "aria-query";
const attr = aria.get("aria-checked");
console.log(attr.type);
Тип может быть:
booleantristatetokennumberАнализатор может обнаружить ошибку:
<div role="checkbox" aria-checked="maybe"></div>
Значение maybe не соответствует допустимому типу.
Наиболее распространённый сценарий использования
aria-query — создание правил для линтеров.
Например, библиотека eslint-plugin-jsx-a11y использует её для реализации правил:
aria-propsaria-rolearia-proptypesrole-has-required-aria-propsno-redundant-rolesКаждое правило:
aria-queryТакой подход обеспечивает автоматическую проверку доступности интерфейсов на этапе разработки.
Карта roleElements позволяет определить, какие
HTML-элементы могут реализовывать конкретную роль.
Пример:
import { roleElements } from "aria-query";
const elements = roleElements.get("checkbox");
console.log(elements);
Результат может включать:
input[type="checkbox"]
Это позволяет выявлять случаи, когда разработчик использует сложную ARIA-реализацию там, где существует нативный HTML-элемент.
Например:
<div role="checkbox" aria-checked="true"></div>
Анализатор может предложить заменить конструкцию на:
<input type="checkbox">
В спецификации ARIA роли могут наследовать свойства других ролей.
Например:
switch → checkbox
Это означает, что switch наследует многие свойства
checkbox.
Информация о наследовании содержится в поле:
superClass
Пример:
const switchRole = roles.get("switch");
console.log(switchRole.superClass);
Анализатор должен учитывать наследование при проверке допустимых свойств и состояний.
Инструмент анализа доступности на основе aria-query
обычно состоит из следующих модулей:
1. Парсер
Преобразует код в AST.
2. Сканер JSX/HTML
Находит элементы и их атрибуты.
3. Семантический анализатор
Использует данные aria-query для проверки:
4. Система отчётов
Формирует:
Несмотря на широкие возможности, статический анализ имеет ограничения.
Некоторые ошибки невозможно выявить без выполнения кода:
Поэтому статический анализ часто комбинируется с:
Использование библиотеки позволяет создавать инструменты, которые:
Статический анализ на основе aria-query стал фундаментом
большинства современных инструментов проверки доступности в экосистеме
JavaScript.