WebValid
WebValid Team

Иллюзия чистого кода: Почему линтеры (ESLint) не спасают от логических ошибок ИИ

ESLint AI Vibe-Coding QA Accessibility

Tech Stack: В примерах используется React и Next.js App Router, но принципы дебаггинга ИИ-кода применимы к любому современному фронтенд-стеку (Vite, Vue, Svelte).

Ваш проект сияет. Вы только что «навайбили» (vibe-coded) целую пачку компонентов в Cursor или Copilot, и это было чертовски быстро. Вы запускаете npm run lint, и терминал выдает девственно чистый результат: «0 errors, 0 warnings». Вы чувствуете себя богом продуктивности. Но как только дело доходит до деплоя или первой проверки на стейджинге, всё разваливается: поисковики не видят страницы, скринридеры спотыкаются о пустые кнопки, а сайт в Safari выглядит как привет из 90-х.

Проблема в том, что мы слишком доверились линтерам. ESLint — это роскошный инструмент для проверки синтаксиса и соблюдения стиля, но он абсолютно слеп к результату вашего кода в реальном браузере. Линтер видит «намерения» разработчика, а WebValid видит то, что реально получил пользователь.

В эпоху ИИ-кодинга, когда нейронки генерируют код пачками, статическая проверка (accessibility testing) стала опасной иллюзией безопасности. Давайте разберем «Галерею слепых пятен», где ваш линтер — просто бесполезный декоратор.


1. Пробелы в доступности: Когда alt есть, а смысла — нет

🔴 High · Провал доступности · WCAG 1.1.1 (Non-text Content)

Линтер — это программный алгоритм, он проверяет наличие атрибута. Если вы используете eslint-plugin-jsx-a11y, он поставит галочку, как только увидит тег alt. Но он не может оценить, что именно там написано.

Что делает ИИ (Before): Нейронки часто ленятся и генерируют «технические» описания или используют названия файлов в качестве заглушек.

// ❌ Линтер считает этот код идеальным (атрибут alt формально присутствует)
<img src="/assets/hero-bg.jpg" alt="image" />
<img src="/icons/checkmark.svg" alt="checkmark_icon_final_v2.svg" />

В чем проблема: Для скринридера alt="image" — это просто шум, а чтение названия файла — бессмыслица. Линтер «доволен», но ваш UI остается недоступным.

Важно понимать: инструменты автоматизации (включая Axe-core) покрывают максимум 20-30% проблем WCAG. Они не «понимают» смысл картинки (не отличат танк от собаки), но они отлично находят технические анти-паттерны: пустые ссылки, дублирующиеся описания или использование зарезервированных слов («photo», «image»), которые ИИ обожает подставлять по умолчанию.

Как ловит WebValid (The Truth): Рантайм-аудит анализирует не исходный код, а итоговый DOM. Он находит эти «мусорные» заглушки и подсвечивает места, которые требуют ручного или ИИ-аудита смысла. Это эффективный фильтр, который отсекает технический брак, прежде чем вы позовете тестеров.

Подробнее о том, как ИИ ломает семантику разметки, читайте в нашем разборе «Топ 7 ошибок доступности ИИ».


2. Мертвые ссылки: То, что «зеленый линтер» не видит

🟡 Medium · Потеря трафика · SEO Health

ИИ отлично пишет локальные файлы, но он понятия не имеет о структуре вашего сайта на стейджинге или в продакшене. Он может сгенерировать идеальную навигацию, которая будет вести в никуда.

Что делает ИИ (Before): Вы просите «сделай меню с ценами и фичами». ИИ генерирует:

// ❌ Код синтаксически верный, линтер счастлив
<Link href="/pricing">Цены</Link>
<a href="#features">Наши фичи</a>

В чем проблема: Страница /pricing могла быть удалена вчера или переименована в /plans. Якорь #features может отсутствовать в итоговом DOM, потому что ИИ назвал секцию id="our-features". Линтер никогда не узнает о 404-й ошибке или «мертвом» переходе, пока вы сами на него не нажмете.

Как ловит WebValid (The Truth): Network Scanner и Sitemap Scanner буквально проходят по каждой ссылке на отрендеренной странице. Они обнаружат, что страница /pricing вернула 404, а якорь #features не привязан ни к одному элементу. Это проверка «внешней правды», которая недоступна статическому анализу.


3. SSL-сертификат истёк, а вы узнаёте об этом последним

🔴 Critical · Сайт заблокирован · OWASP A05:2021 (Security Misconfiguration)

Есть категория багов, которые вообще не живут в коде. Они живут в конфигах сервера, и никакой ESLint до них не дотянется.

Что делает ИИ (Before): ИИ предлагает подключить какой-то полезный скрипт или шрифт по хардкодной ссылке:

<!-- ❌ В коде всё чисто -->
<script src="http://cdn.example.com/analytics.js"></script>

В чем проблема: Если ваш сайт на HTTPS, браузер заблокирует этот скрипт как Mixed Content (смешанный контент). Более того, ваша политика безопасности (CSP) может запрещать загрузку скриптов с внешних доменов. Линтер видит только текстовый файл и говорит: «Ок». В итоге кнопка аналитики не работает, а в браузере горит серая иконка «Not Secure». Или, что еще хуже, ваш SSL-сертификат истекает через 2 дня — линтер об этом промолчит.

Как ловит WebValid (The Truth): SSL Scanner и Security Scanner проверяют ответ сервера. Они видят, что сертификат скоро «протухнет», а браузер ругается на незащищенные ресурсы. Это тот уровень «правды», который проявляется только на живом адресе.


4. Прыгающая верстка: Почему CLS убивает конверсию

🟡 High · Раздражение пользователя · Core Web Vitals (CLS)

В современных фреймворках вроде Next.js линтеры действительно научились ловить отсутствие размеров у картинок (требуя width и height для компонента <Image>). Но «зеленый» линтер всё еще не гарантирует стабильную верстку в браузере.

Что делает ИИ (Before): ИИ может правильно использовать компоненты фреймворка, но он не видит контекст загрузки всей страницы. Он может сгенерировать идеальный код, который всё равно «прыгнет» из-за внешних факторов.

В чем проблема: Cumulative Layout Shift (CLS) — это метрика рантайма. Ваш линтер абсолютно слеп к тому, что:

Линтер проверяет пропсы, а WebValid замеряет реальный опыт. Даже если ваш код проходит все проверки next/image, итоговый CLS может быть красным из-за инфраструктурных багов, которые видны только в браузере.

Как ловит WebValid (The Truth): Lighthouse Scanner замеряет визуальную стабильность в реальном времени. Он «проживает» загрузку страницы как реальный пользователь и фиксирует каждое смещение макета, выставляя оценку на основе того, что пользователь увидел, а не того, что разработчик написал.

Хотите узнать больше о визуальных багах? Смотрите руководство «Топ 5 ошибок ИИ в CSS».

Ваша верстка «прыгает»? Замерьте реальный CLS в браузере прямо сейчас.


5. Конкурирующие ID: Когда компоненты ломают друг друга

🟡 Medium · Сломанный функционал · HTML5 Validity

ИИ работает в ограниченном контексте. Когда вы просите его создать «компонент формы», он создаёт его в изоляции.

Что делает ИИ (Before): Вы создали компонент ContactForm и AuthForm. ИИ в обоих случаях использовал типичный ID для кнопки:

// Файл ContactForm.tsx
<button id="submit-btn">Отправить</button>

// Файл AuthForm.tsx
<button id="submit-btn">Войти</button>

В чем проблема: Линтер проверяет каждый файл отдельно. Для него id="submit-btn" внутри одного файла — это норма. Но когда вы выводите обе формы на одну страницу (например, в лендинге), ваш DOM становится инвалидным. Два элемента с одинаковым ID — это катастрофа для JavaScript-логики и экранных дикторов. Скринридер просто «потеряет» одну из кнопок, а ваш скрипт document.getElementById вернет не тот элемент.

Как ловит WebValid (The Truth): HTML Syntax Scanner анализирует итоговый отрендеренный HTML-код всей страницы. Он мгновенно обнаружит дубликаты ID, которые были «невидимы» для линтера, пока компоненты жили в разных файлах.

О том, как «галлюцинации» в DOM мешают росту продукта, мы писали здесь.


6. Ошибки гидратации: Когда сервер и браузер не договорились

🔴 High · Белый экран · React Hydration Error

Это самый коварный баг современного фронтенда. ИИ обожает использовать проверки вроде typeof window !== 'undefined'.

Что делает ИИ (Before): Нейронка пытается адаптировать код под браузер:

// ❌ Линтер видит валидный JS
const isMobile = typeof window !== "undefined" && window.innerWidth < 768;

return <div>{isMobile ? "Mobile View" : "Desktop View"}</div>;

В чем проблема: На сервере (SSR) window нет, поэтому отрендерится ‘Desktop View’. Но как только страница загрузится в браузере, React увидит, что на самом деле это ‘Mobile View’. Произойдет Hydration Mismatch. В лучшем случае у вас «поплывет» верстка, в худшем — всё приложение упадет с ошибкой, оставив пользователя перед белым экраном. Линтер считает этот код безопасным, потому что синтаксически тут всё логично.

Как ловит WebValid (The Truth): WebValid запускает ваш проект в реальном Headless-браузере. Если в консоли проскакивает ошибка гидратации или рантайм-эксепшн, Network Scanner (в режиме аудита консоли) зафиксирует это как критический баг.


7. Дырявый бандл: Ваши API-ключи в открытом доступе

🔴 Critical · Утечка данных · OWASP A01:2021 (Broken Access Control)

Это самый опасный баг, который ИИ может «подарить» вашему проекту. При генерации кода нейронки часто используют заглушки или просят вас вставить ключи напрямую, «чтобы просто проверить».

Что делает ИИ (Before): Вы просите ИИ добавить интеграцию со Stripe или Firebase. ИИ генерирует клиентский конфиг и услужливо вставляет туда секретный ключ или токен, который должен жить только на сервере.

// ❌ Линтер видит валидный JS-объект. Он не знает, что это секрет.
export const stripeConfig = {
  publicKey: "pk_live_...",
  secretKey: "sk_live_...", // ⚠️ КРИТИЧЕСКАЯ УТЕЧКА
};

В чем проблема: Линтер проверяет синтаксис. Для него любая строка — это просто строка. Но как только этот код попадает в бандл, ваш секретный ключ становится доступен любому, кто откроет DevTools. Злоумышленники используют ботов для сканирования JS-файлов на наличие sk_live, aws_key и других паттернов. Результат: опустошенные счета и скомпрометированные данные пользователей.

Как ловит WebValid (The Truth): Security Scanner анализирует не исходники, а итоговый скомпилированный бандл, который получает браузер. Он использует базу из тысяч паттернов известных сервисов и мгновенно поднимает тревогу, если в публичном коде обнаружен секретный токен или «забытый» дебаг-режим.

Разбор того, как Next.js и Vite бандлы раскрывают секреты, доступен в статье «Утекшие API-ключи».


WebValid vs Lighthouse: Почему не просто «axe в CI»?

Технический читатель спросит: «Зачем мне отдельный сервис, если есть Lighthouse и axe DevTools?». Ответ в барьере входа и охвате:

  1. Reality vs Lab: Lighthouse в CI проверяет «стерильную» версию. WebValid проверяет живой адрес со всеми его сетевыми задержками, протухшими SSL и упавшими CDN.
  2. Zero-Config: Чтобы встроить axe в CI, нужно писать YAML-конфиги, настраивать раннеры и хранить логи. В WebValid вы просто вводите URL и получаете отчет в Markdown, готовый для промпта в Cursor.
  3. Мониторинг 24/7: Линтер и CI работают только в момент коммита. Сертификат может истечь, а API-ключ — утечь через сторонний скрипт в любое время. WebValid следит за этим постоянно.

Fact-Check: Долговая яма доступности

Чтобы понять, что это не пустые страшилки, взглянем на цифры. Линтеры широко распространены в современной разработке, однако это не коррелирует с качеством доступности — что косвенно подтверждает отчет WebAIM Million 2024, в котором проанализировали топ-1 миллион главных страниц сайтов:

Почти все эти сайты проходят стандартные проверки npm run lint. Линтер умеет бить по рукам за лишний пробел, но он разрешает вам выпускать в мир цифровой мусор, который невозможно использовать.


Как это работает вместе: ESLint + WebValid

Не нужно отказываться от линтеров. Они — ваша первая линия обороны. Но они не могут быть последней.

ВозможностьESLint (Static)WebValid (Runtime)
Синтаксические ошибки✅ Поймает сразу❌ Не для этого
Качество alt-текстов❌ Проверит только наличие✅ Оценит смысл и полезность
SSL и сертификаты❌ Слепой✅ Мониторит 24/7
Broken links (404)❌ Слепой✅ Проверяет каждый URL
Layout Shift (CLS)❌ Слепой✅ Замеряет в браузере
Ошибки гидратации❌ Слепой✅ Ловит в консоли
Утечка ключей в бандле⚠️ Только паттерны в коде✅ Сканирует итоговую сборку

Внедряем WebValid в ваш Vibe-кодинг

Веб-аудит в 2026 году — это не скучный PDF для менеджера. Для соло-разработчика и «вайб-кодера» это точный промпт на исправление багов, которые линтер не в состоянии даже заметить.

Когда запускать аудит?

Что вы получаете через 60 секунд: Вы вводите URL стейджинга и получаете Markdown-отчет. Не нужно ничего настраивать, писать YAML-конфиги или ждать завершения пайплайна в CI. Отчет содержит готовые ai-fix инструкции: просто скопируйте их и вставьте в Cursor или ChatGPT.

Ваш новый чек-лист качества:

  1. Lint: ESLint причесывает синтаксис (5 сек).
  2. Deploy: Код летит на Vercel/Netlify Preview (30 сек).
  3. Audit: WebValid проверяет «живую» правду (60 сек).
  4. Fix: Вы скармливаете Markdown-отчет своему ИИ и чините всё за один промпт.

Цифровая чистота — это когда линтер зелёный в редакторе, а WebValid подтверждает, что ваш продукт доступен, безопасен и быстр в реальном мире.

Не гадайте, что сломал ваш ИИ сегодня. Получите детерминированный список логических и рантайм-багов вашего сайта прямо сейчас. Первый отчет бесплатно, без регистрации и сложных настроек.

Запустить аудит на webvalid.dev


Официальные ресурсы и документация

Эта статья была полезна?