lenec ru

← все посты

Vale и Alex как линтеры документации: что в них реально полезно

17K

Документация написана, но в ней десять разных стилей. Один автор пишет «нажмите кнопку», другой — «нужно нажать на кнопочку». В одной странице — Imperative («Run the command»), в другой — descriptive («The command is run by...»). На ревью всё это редактору приходится править руками, и он либо пропускает половину, либо тратит на ревью больше времени, чем на написание.

Документацию нужно линтить так же, как код. Линтер не заменяет редактора, но снимает рутину: ловит запрещённые слова, длинные предложения, пассивный залог, запутанные конструкции. Vale и Alex — два самых популярных линтера для текста, и у них разная задача. Разберу, что они умеют, чем отличаются, как настроить и какие правила реально полезные.

Что такое Vale

Vale — это линтер прозы общего назначения. Открытый, на Go, работает локально и в CI. Принимает на вход Markdown, AsciiDoc, HTML, reStructuredText, и набор правил (стайлгайдов). Каждое правило — YAML-файл с описанием, что искать и что говорить, если нашлось.

Установка:

brew install vale          # macOS
go install github.com/errata-ai/vale/v3@latest   # любая платформа

Базовый конфиг .vale.ini:

StylesPath = .vale/styles
MinAlertLevel = suggestion

[*.md]
BasedOnStyles = Microsoft, write-good

Vale качает стайлгайды через vale sync. Microsoft — официальный гайд от Microsoft, проверенный в индустрии. Write-good — небольшой набор правил про активный залог, длинные слова, ненужные наречия.

Запуск:

vale docs/

Вывод — список ошибок с указанием файла, строки, правила:

docs/intro.md
 12:5  warning  Avoid using 'very' to add emphasis.       Microsoft.Avoid
 24:1  error    Use active voice instead of passive.      write-good.passive

Какие правила Vale реально полезны

Из коробки в Microsoft и write-good — десятки правил. Не все стоит включать сразу.

Реально полезные:

  • Запрещённые слова. Например, Microsoft.We — предупреждает про «we», когда стиль требует обращения к читателю.
  • Жаргон. Microsoft.Jargon ловит «utilize» вместо «use», «leverage» вместо «use».
  • Длина предложений. Microsoft.Wordiness предлагает короче.
  • Двойные пробелы, лишние знаки пунктуации.
  • Capitalization в заголовках: либо везде Title Case, либо везде Sentence case — но не вперемешку.

Скорее раздражают:

  • «Pre-flight checks» — правила вида «возможно, вы хотели сказать иначе». Слишком много false positive.
  • Жёсткое требование active voice для всех случаев. В техническом тексте passive часто оправдан.
  • Запрет терминов вроде «obvious», «simply» — иногда они уместны.

Лучшая практика: включить набор постепенно. Начать с одного-двух стайлгайдов, посмотреть, что они находят, выключить ложные срабатывания через .vale/styles/Vocab/myproject/accept.txt.

Свои правила Vale

Сильная сторона Vale — расширяемость. Своё правило — это YAML:

# .vale/styles/MyTeam/Forbidden.yml
extends: existence
message: "'%s' — устаревший термин, замените на %s."
level: error
ignorecase: true
swap:
  whitelist: allowlist
  blacklist: denylist
  master/slave: leader/follower

Этот файл проверяет наличие устаревших терминов в тексте и предлагает замены. Простой YAML, но покрывает 80% случаев. Ничего сложнее обычно не нужно.

Полезные типы правил, которые встроены:

  • existence — слово/фраза не должна встречаться.
  • substitution — одно слово заменить на другое (как в примере выше).
  • occurrence — слово может встречаться не более N раз.
  • repetition — одно и то же слово два раза подряд.
  • capitalization — заголовки в нужном регистре.
  • spelling — опечатки против словаря.
  • readability — индексы читабельности (Flesch, Gunning Fog).

Vale — про стиль и формальные требования. Он не понимает смысл текста, но умеет ловить шаблонные ошибки.

Что такое Alex

Alex — линтер для другой задачи: ловит формулировки, которые могут быть неуместными, оскорбительными или гендерно-окрашенными. Open source, на Node.js.

Установка и запуск:

npm install -g alex
alex docs/

Что Alex проверяет:

  • Гендерно-нейтральные формулировки. «Each developer should write his code» → подсказка использовать «their».
  • Устаревшие или проблемные термины. «Master/slave», «whitelist/blacklist», «sanity check» — предлагает замены.
  • Формулировки, которые могут восприниматься как обидные. «Just do X» → «Just» снижает значимость задачи.
  • Apparently exclusionary language. «Guys» в обращении к группе.

Пример вывода:

docs/setup.md
  3:14  warning  `master` may be insensitive, use `primary`, `main` instead   master  retext-equality
  8:1   warning  Don't use `simply`, it's dismissive                           simply  retext-simplify

Где Alex полезен, где избыточен

Полезен:

  • В open source проекта с разнообразным сообществом. «Whitelist» в 2026 уже почти везде заменён на «allowlist».
  • В корпоративной документации, где есть требования по inclusive language.
  • Для ловли «just», «simply», «easy», «obviously» — слов, которые звучат покровительственно.

Избыточен:

  • Ловит слишком много false positive. Слово «host» в контексте «server host» Alex может пометить.
  • Не различает контексты. «Black box» в смысле «непрозрачная система» он подсветит, хотя термин нейтральный.
  • Правила запрограммированы, не настраиваются гибко. Можно отключить целые наборы, но кастомные правила писать сложно.

Я обычно включаю Alex с --quiet (только warnings, не info-сообщения) и profanity-level=0. Игнорирую те правила, которые ломают конкретный домен (например, «kill» в context unix-команд).

Vale + Alex или один из двух

Они закрывают разные задачи:

  • Vale — про стиль, длину, запрещённые слова, технические термины. Кастомизируется под проект.
  • Alex — про inclusive language. Готовый набор правил, минимум настройки.

Если выбирать один — Vale. Он гибче, в его правилах можно записать всё, что есть в Alex, плюс свой стайлгайд.

Если использовать оба — Alex как первый проход (быстро), Vale как основной (детально). У них непересекающиеся жалобы, и разделение помогает не путать «стиль» и «inclusive language».

Интеграция в CI

Локально линтер запускается перед коммитом. В CI — на каждый PR.

GitHub Actions для Vale:

name: Lint docs

on:
  pull_request:
    paths:
      - 'docs/**'

jobs:
  vale:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: errata-ai/vale-action@reviewdog
        with:
          files: docs/
          reporter: github-pr-review

Action vale-action публикует комментарии в PR на нарушенных строках. Reviewer видит линтер-замечания прямо в коде, можно accept/dismiss.

Уровни алертов в Vale:

  • suggestion — мелкие подсказки, не блокирующие.
  • warning — стоит обратить внимание.
  • error — нарушение правила, требует исправления.

В CI обычно ставлю порог на error для блокировки, warning и ниже — для информации в PR. Это компромисс: PR не блокируется на каждой мелочи, но критичные нарушения видны.

Что чаще всего оказывается в локальном стайлгайде

Для команды я обычно начинаю с такого набора правил:

# .vale/styles/MyTeam/SubstitutionList.yml
extends: substitution
message: "Замените '%s' на '%s'"
level: warning
ignorecase: true
swap:
  whitelist: allowlist
  blacklist: denylist
  blackbox: opaque
  click here: имя ссылки
  please: ""           # вежливость в доке избыточна
# .vale/styles/MyTeam/Concise.yml
extends: substitution
message: "Можно короче: '%s' → '%s'"
level: suggestion
ignorecase: true
swap:
  utilize: use
  in order to: to
  due to the fact that: because
  at this point in time: now
# .vale/styles/MyTeam/Headings.yml
extends: capitalization
message: "Используй sentence case в заголовках"
match: $sentence
scope: heading
level: warning

Эти три файла покрывают 90% поверхностных проблем. Дальше расширять только когда становится ясно, что какой-то паттерн повторяется.

Что линтер не делает

Это важно держать в голове с самого начала.

  • Не проверяет, что текст правильный по сути. Если в туториале неверная команда, линтер не заметит.
  • Не оценивает структуру. Длинная вступительная секция и отсутствие чёткой цели в туториале — линтер не увидит.
  • Не ловит логические противоречия. «Установите версию 5», а ниже «Минимум — версия 6» — пропустит.
  • Не проверяет работающие примеры. Команда в коде может быть устаревшей или с опечаткой — нужны другие проверки.

Линтер — это автоматическая проверка стиля, а не редактор. Он экономит редактору время на рутину, но не заменяет ревью текста человеком.

Постепенное внедрение

Включить Vale на 500-страничный проект целиком — самоубийство. CI завалит тысячами замечаний, команда быстро привыкнет игнорировать алерты.

Рабочий план:

  1. Выбрать один-два правила, которые точно полезны (например, запрет «whitelist», sentence case в заголовках).
  2. Запустить локально, посмотреть, сколько замечаний.
  3. Поправить вручную или через скрипт-замену.
  4. Включить в CI как error.
  5. Добавить следующее правило. И так по одному.

Через пару месяцев в проекте 10-15 правил, и они реально работают. Больше обычно не нужно.

Чек-лист внедрения

  • .vale.ini в корне репозитория, в репо.
  • Один стайлгайд из коробки (Microsoft, Google, write-good) как база.
  • Свой стайлгайд .vale/styles/MyTeam/ с правилами под проект.
  • Глоссарий accept.txt с допустимыми терминами проекта.
  • CI запускает Vale на PR с изменениями в docs/.
  • Уровень error блокирует мерж.
  • Есть инструкция, как запустить локально и как добавить новое правило.
  • Раз в квартал команда смотрит, какие правила срабатывают чаще всего, и решает, оставлять или нет.

Vale и Alex не делают тексты идеальными, но снимают с редактора рутину и удерживают единый стиль в команде. Без них документация на проекте, где пишут пять человек, превращается в патчворк. С ними — это всё ещё патчворк, но с предсказуемой формой.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.