ARFA Generator — ядро автоматизации процессов frontend-разработки, или пропущенный этап развития тулинга

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Спустя полгода адаптации к OpenSource выпускаю еще две библиотеки из моего рабочего контура в одном npm-пакете - ARFA Generator и api-contract-check. В этой статье расскажу про первый инструмент, а второй презентую в рамках отдельной статьи.

Когда-то давно я уже писал статью про удобство использования файловых генераторов, интегрированных в долгоживущий процесс dev-сборки, однако за несколько лет развития и обкатки в реальных проектах концепт существенно расширился. Удобнее всего оказалось сместить бандлер с центрального места в один из сайд-эффектов после стабилизации кодовой базы, а разнородные инструменты проверки качества объединить в единый пайплайн с инкрементальным watch-режимом.

В статье не буду пересказывать документацию на русском и английском, а расскажу, как я пришел к такой схеме, насколько она улучшает DX, помогает людям быть продуктивнее, LLM-агентам сжигать меньше токенов, а кодовой базе не расползаться со временем и проще мигрировать между архитектурами.

1. Бандлеры захватывают цикл разработки

Во времена Gulp процесс бандлинга воспринимался как последовательная серия трансформаций исходного кода, результат которой - подготовленные для браузера файлы:

browserify('./index.js').bundle()
  .pipe(source('bundle.min.js'))
  .pipe(buffer())
  .pipe(terser())
  .pipe(gulp.dest('dist'))

Сервер для разработки и перезагрузка браузера настраивались отдельными программами. Впоследствии Webpack / Vite решили скрыть процедурный пайплайн за декларативной конфигурацией и внедрили сервер + HMR, получив название "бандлеры". Со временем именно они стали дефолтной точкой входа в процесс разработки, однако роль инструмента не изменилась - это "часть пайплайна, которая упаковывает артефакты для браузера", то есть просто операции над стабилизированным исходным кодом.

Мысль: у библиотек для сборки есть давно определенная роль, и их вполне можно встраивать в более широкое ядро разработки, учитывая, что сейчас и дев-сервер, и перезагрузка браузера по SSE пишутся в несколько строк и не являются ограничением.

2. Исходный код - тоже артефакт

Иногда создается ложное ощущение, что наш код - истина в конечной инстанции. Да, конечно он трансформируется транспилятором, фреймворками (особенно это видно по шаблонам jsx или vue), переименовывается минификатором, но у программиста остается полный контроль и единоличная ответственность.

Однако то, что мы называем "тулингом" давно и прочно вошло в разработку. Eslint, Prettier, Oxc, Biome получили возможность не только давать рекомендации по исправлению кода, но и напрямую его редактировать. TSC, bun check, tsrs - контролируют корректность типизации и заставляют переписать код. Есть и много других детерминированных анализаторов и инструментов, которые напрямую влияют на вид и содержание кода, включая codegen-утилиты.

Это хороший тренд - ответственность теперь не только на одном разработчике, а "коллективная" - насколько качественно настроишь инструменты, настолько это снизит пространство ошибок в программе и улучшит условно-измеримые характеристики исходного кода вроде "согласованности между всеми разработчиками в команде" и "понятности для коллег". Но, к сожалению, все эти библиотеки - отдельные cli инструменты, и не имеют общего канала предоставления отчетов.

С приходом LLM у исходного кода появился еще один редактор с непредсказуемыми изменениями и собственными ограничениями, часть которых компенсируется именно детерминированными инструментами.

Мысль: на исходный код влияет множество участников с разной степенью контроля и предсказуемости, но они не объединены в единый пайплайн и не имеют общей обратной связи или истории внесенных изменений.

3. Бойлерплейт и пустая трата времени

Возможности детерминированного контроля исходного кода в настоящее время сильно недооценены. В процессе разработки любого проекта возникают рутинные задачи:

  • при написании нового редюсера нужно его добавить в общий файл и написать экшен

  • если в проекте договорились импортировать утилиты из одной точки, добавленный getTime.ts нужно не забыть добавить в реэкспорты

  • новые тексты в интерфейсе нужно синхронизировать с облачной системой переводов, не забывая удалять неиспользуемые ключи

  • присланные бэкендом данные необходимо валидировать и очищать от лишнего, чтобы не сломался Object.keys в легаси-коде

  • при изменениях нужно поддерживать актуальность документации и т.п.

Я привел лишь небольшое количество сценариев - в документации ARFA Generator приведены решения для десятков типовых задач: из структуры файлов, их наименования и контента можно вывести большое количество потенциально автоматизируемых операций. Сегодня разработчики вынуждены выполнять их вручную из-за отсутствия подходящих инструментов, времени для их создания, или потому что "здесь всегда так делали".

Мысль: можно значительно сократить ручную работу и уменьшить когнитивную нагрузку и без использования LLM-агентов.

4. Архитектура - тоже артефакт

Существует множество определений "архитектуры", но применительно к фронтенду обычно подразумевают "структуру файлов и модулей, включая именование", "границы ответственности" и "организацию потока данных". Часто это содержится только в устных договоренностях или документации, но может закрепляться в статическом анализе вроде eslint boundaries или даже выбрасывать исключение в рантайме (что часто делают в React при попытке подключиться к недоступному контексту).

Однако эти механизмы не дают целостного представления, и с ростом кодовой базы становится все сложнее отслеживать расхождения и дублирование. Для меня же основные критерии качества архитектуры - то, что ее можно сериализовать из кода, восстановив большую часть исходных правил; при необходимости без особых сложностей заменить на другую; детерминированно проверять соответствие принципам в едином пайплайне:

  • Первый инструмент проверяет, что экспортируемая функция / константа / стор именованы согласованно с названием файла

  • Второй строит сводную карту слоев (например, всех сторов, экшенов, роутов) или модулей / фич, по которой легко проверить дубляжи, несогласованный нейминг или случайно появившиеся лишние сущности

  • Третий проверяет соблюдение границ импортов

  • Четвертый по шаблону создает бойлерплейт или каркас новых модулей в соответствии с выбранным подходом

  • Пятый строит карты рантайма, показывающие, например, какие сущности доступны на конкретной странице. Это упрощает ревью и в ряде случаев позволяет быстрее найти проблемы

  • Шестой автоматически актуализирует документацию

При этом пайплайн должен уметь показывать и при необходимости удалять автоматически контролируемые файлы, позволяя изменить правила и легче мигрировать на другую архитектуру.

Мысль: фиксировать соглашения удобнее не в документах, а в детерминированных правилах с общей историей нарушений и списком контролируемых файлов.

5. Единый пайплайн

Итак, все предыдущие мысли наводят к закономерному выводу: ядром процесса должен быть не бандлер, который просто делает одну из операций, а реактивный инструмент, объединяющий разрозненный тулинг в единый процесс. Тут и выходит на сцену ARFA Generator, которым я пользуюсь в крупных проектах уже много лет, и который заиграл новыми красками после распространения ИИ. Он работает со следующими слоями:

  • Плагины - это мутирующие исходный код инструменты. Они запускаются итеративно - в цикле каждый из плагинов получает данные о модификациях, проведенных другими плагинами, пока кодовая база не стабилизируется. Могут писать, модифицировать и удалять файлы

  • Чекеры - это немутирующие исходный код инструменты, например tsc / eslint / test-runner / AST rules enforcer. Выполняются после плагинов одним проходом - здесь нет необходимости в каскадных итерациях

  • afterCheckers - немутирующий исходный код колбэк, подходит для запуска бандлера в едином пайплайне vite.build / esbuild.build / bun.build, то есть для превращения стабилизированного и проверенного кода в другую форму - для браузера, документации или внешнего анализа

  • afterFinish - потенциально мутирующий код колбэк. Получает логи всех предыдущих этапов для вывода в консоль, а также здесь оптимально вызывать перезагрузку браузера или сигнализировать другим системам, что процесс полностью прошел. Можно вызвать и LLM-агента, который изменит файлы и дальше запустит новый полный цикл

Этот пайплайн можно вызывать единожды (для CI) или в watch-режиме для локальной разработки. Для LLM-агентов также есть отдельная точка входа в виде команды cli, через которую можно получить информацию о последнем цикле в markdown-формате с дефолтными инструкциями "исправлять первую значимую ошибку". При этом в самом пайплайне уже зафиксирован вызов определенных инструментов для каждого файла - ИИ не нужно это предсказывать, а человеку - задумываться при разработке.

Также слежение за всем исходным кодом, включая добавление новых файлов, позволяет сразу их включать в архитектуру, в отличие от watch-режима бандлера, который не следит за файлами, отсутствующими в графе импортов (или следит, но никак не учитывает и не встраивает в известный граф).

6. Почему единый пайплайн стал возможным

За недолгое время существования веб-разработки тулинг значительно развился. Раньше мысль о подобном пайплайне скорее пугала - ведь внедрение всех этих операций в цикл разработки означал бы не только 40 условных секунд пересборки на Webpack, а плюс столько же времени работы каждого из инструментов. Поэтому большинство разработчиков использовало схему дев-разработки через watch режим бандлера - это давало хоть немного приемлемую производительность, а остальные инструменты запускались на pre-commit или в CI.

Однако сейчас инструменты становятся настолько быстрыми, что эта схема является устаревшей. Сейчас пайплайн из плагинов + bun check / tsgo + Biome + bun test + esbuild для проектов размером около 100 страниц на Реакте занимает меньше 2 секунд (по замеру на ряде проектов, которые делал), а кроме того ARFA Generator дает механизмы их запуска только с изменившимися файлами, что еще больше ускоряет операции. Таким образом, и человек, и LLM-агент очень быстро получают фидбек ото всех инструментов без дополнительной когнитивной нагрузки / сжигания токенов на то, какой инструмент сейчас стоило бы вызвать.

7. Пропущенный этап развития тулинга

Верхнеуровнево для меня процесс обучения веб-разработке и в целом глобальное развитие подходов в разработке выглядит так:

  1. Обучение с нуля, все пишется руками. В мире это означало отсутствие готового тулинга и были только базовые примитивы в виде языков программирования и browser API

  2. Изучение готовых фреймворков и библиотек. Это время становления экосистемы и разделения мира фронтенд-разработчиков по фреймворкам, развитие tsc / eslint и другого тулинга

  3. Понимание ограничений и написание своих библиотек, решающих ряд необходимых задач эффективнее. В мире увеличивается количество разработчиков, инструментов, создается много компактных альтернатив раздутым "традиционным" решениям

  4. Детерминированная автоматизация вроде ARFA Generator для гибкого объединения инструментов и избавления от надоевшего ручного бойлерплейта

  5. Эпоха недетерминированной генерации на основе уже достаточно проработанных и стабильных исполняемых правил в проекте

И вот четвертый этап во фронтенде почему-то недопрошли - его мало кто применяет в реальности и еще меньше тех, кто о нем пишет или публикует библиотеки. При этом проблемы, перечисленные в этой статье никуда не делись, а ИИ через фразу указывает на отсутствие формализованных правил и механизма их передачи. Уже приевшийся термин harness пытается это решить "текстовыми описаниями архитектуры в md файлах", "правилами, какой инструмент вызывать при изменениях", "описанием loop до исчезновения всех ошибок" и т.п. Но все понимают, что это мягко говоря неэффективно при работе с недетерминированными и часто меняющимися LLM.

Когда я столкнулся с LLM, долго не понимал куда его применить, учитывая что тогда ее возможности были ограниченны:

  • "Избавить от ручного бойлерплейта" - я и так пишу только значимую бизнес-логику, остальное детерминированно, бесплатно и быстро генерируется

  • "Набросать черновики" - очень специфичная задача, как правило после груминга в голове уже выстраивается карта необходимого решения с учетом специфики проекта и мнений коллег, а в компаниях производящих "экспериментальные микро-mvp для быстрой проверки гипотез" я не работал

  • "Написать бизнес-логику" - задачи часто приходят с недостаточным описанием, и куда быстрее написать код самому, чем продумать и создать полноценное "описание кода на естественном языке"

Сейчас возможности моделей и агентов сильно улучшились, поэтому добавил в ARFA Generator cli-режим фидбека, хотя в продакшене все еще очень мало им пользовался - все еще быстрее написать руками, чем читать много чужого текста и кода, но возможно кому-то будет полезно.

Для быстрой проверки, чем эта библиотека может быть полезна в вашем проекте - передайте ИИ llms.md, это единый файл с документацией и примерами, чтобы не тратить токены на Vitepress html разметку. Вот ссылка на репозиторий, а я пойду неспешно писать статью про следующий выложенный инструмент - он тоже довольно интересный и концептуальный.

Источник: https://habr.com/ru/articles/1095018/


Интересные статьи

Интересные статьи

Битрикс24 Коворк/Код — новый ИИ-агент, который может работать с данными портала и выполнять действия по обычному текстовому запросу. На примере объединения дублей в CRM разбираем протокол агента:...
Итак, ты наконец-то нашёл свою первую работу в офисе. Добрая айтишечка или что-то иное — не имеет значения. Самое главное на первые несколько месяцев — не вылететь, да? Я ТАК ДОЛГО ИСКАЛ ЭТУ РАБОТУ ЧТ...
Картинка сгенерированая по запросу "сгенерируй картинку про битрикс24 и искусственный интеллект" неплохо отражает итоговые результаты
Учёные Института биохимической физики имени Н.М. Эмануэля РАН (ИБХФ РАН) создали композиционный материал с антибактериальными свойствами на основе полилактида и антибактериального природного соединени...
Меня зовут Андрей Буйновский, я разработчик в ИТ-компании. Мы с командой решили написать эту статью и поделиться некоторыми проблемами, подводными камнями и их решениями в разработке мобильного прилож...