Платформа витрин
Сопровождение JavaScript-библиотеки, на которой работают витрины inSales
Взял заброшенную библиотеку CommonJS, которая отвечает за карточки товаров, корзину и формы на витринах inSales. Уменьшил сжатый бандл с 300+ до 168 КБ и несколько лет развивал её дальше.
- 300+ КБ → 168 КБ сжатый production-бандл после переделки сборки и зависимостей
- Моя роль
- Мейнтейнер библиотеки: рефакторинг, сборка, компоненты, публичный API, документация
- Период
- Октябрь 2021 – сентябрь 2026
- Навыки
На этой странице
Задача
CommonJS (в документации ещё Common.js и common.v2.js) — JavaScript-библиотека витрин inSales. Она загружает данные товаров, переключает варианты, пересчитывает цены, меняет количество в корзине и отправляет формы. Разработчики магазинов подключают её к шаблонам через data-*-атрибуты и вызывают её публичный API из своего кода. У inSales больше 60 000 магазинов, поэтому ошибка в библиотеке могла сломать выбор товара или корзину сразу на многих сайтах.
Я взялся за неё вскоре после перехода из технической поддержки во фронтенд в 2021 году. Библиотека была фактически заброшена: работала, но весила много, собиралась устаревшей сборкой, и серьёзно её менять никто не хотел. Никто не знал, какие шаблоны и клиентские доработки от какой её части зависят.
Моя роль
Я стал мейнтейнером библиотеки и оставался им несколько лет. Разбирал архитектуру, переделывал сборку, добавлял компоненты и публичные API, писал документацию для разработчиков, готовил сценарии QA и релизы, чинил ошибки в живых магазинах. Серверные API делали бэкенд-разработчики, состав данных я согласовывал с ними. Со временем коллеги и техподдержка стали приходить ко мне с вопросами о том, как работает библиотека.
Что я сделал
Карта зависимостей до первых серьёзных изменений
Сначала нужно было понять код, а не менять его. AI-ассистентов в работе тогда ещё не было, так что я читал код и вручную рисовал карту в Miro: откуда берутся данные товара, когда они попадают в кеш, что запускает рендер, как события корзины приводят к новым запросам и какие модули зависят друг от друга. С этой картой было видно, что затронет правка одного метода за его пределами.
Сборка меньше, поведение то же
Я перевёл сборку на Webpack 5, а модули — с CommonJS-формата require на ES import/export. Название библиотеки осталось прежним. На ES-модулях сборщик видит, что реально используется: tree shaking выкидывает мёртвый код, а code splitting делит сборку на части. Избыточные подключения Lodash я заменил на нужные модули и убрал неиспользуемые зависимости. Сжатый production-бандл уменьшился с более чем 300 КБ до 168 КБ, несжатый файл — примерно с 900 до 600 КБ. Выбор товара, корзина и формы при этом работали как раньше.
Публичный API, на котором строят свои виджеты
Библиотека связывает Liquid-шаблоны, HTML-разметку и данные магазина. Компоненты подключаются через data-*-атрибуты, а Products, Cart, ajaxAPI и EventBus дают разработчикам данные, операции с корзиной и события. Поверх этого я добавил AJAX-загрузку списков товаров, отдельного товара и фильтров каталога с новым товарным кешем (отдельный кейс), товарные опции и дополнительные услуги в карточке и корзине, мультикорзины для оптовых магазинов и невидимую капчу для стандартных и кастомных форм. Мелкие доработки приходили из реальных запросов: хук перед сборкой формы обратной связи (январь 2026) и payload из кнопки, которая открывает форму (июль 2026). В интеграциях корзины я использовал облегчённые события add_items:insales:cart:light и update_items:insales:cart:light. Они срабатывают раньше, но передают позиции корзины без вложенного объекта product, и обработчики приходилось писать под такой формат.
Стандартный шаблон Stories. Кнопки вариантов, цена и счётчик в корзине работают на CommonJS.
Совместимость как правило релиза
Каждая новая версия должна была работать с несколькими поколениями шаблонов и с кодом магазинов, который заранее не увидишь. Я сохранял старые способы подключения компонентов и проверял общий компонент во всех местах витрины, где он встречается. Собирал тестовые версии библиотеки, подключал их к тестовым магазинам, отдавал изменения на ревью и QA и выкатывал по этапам. Для крупных изменений, например выбора провайдера капчи, использовал фича-флаги. Когда после релиза на реальных аккаунтах обнаружился пустой captcha_type, я нашёл причину, поправил обработку настройки и подготовил повторную выкатку системных форм.
Документация и помощь коллегам
Я написал документацию для разработчиков к ui-ajax-products, ui-ajax-product и API для reCAPTCHA и Yandex SmartCaptcha: какую разметку и data-*-атрибуты добавить, какие настройки принимает компонент, как устроены шаблоны отображения, какие события запускают действие и какие сообщают о его завершении. Приводил примеры интеграции. Ещё описал, как подключить к магазину тестовую сборку CommonJS, чтобы проверять изменения до общего обновления. Когда у клиента что-то ломалось, помогал коллегам понять, где причина: в библиотеке, в данных, в ответе сервера или в коде самого магазина.
Результат
- Сжатый production-бандл уменьшился с более чем 300 КБ до 168 КБ, несжатый — примерно с 900 до 600 КБ.
- У библиотеки, которую никто не хотел трогать, появились мейнтейнер и документация к компонентам и публичным API. В 2026 году в неё всё ещё добавлялись новые API.
- На ней построены новые функции витрин: AJAX-загрузка товаров с кешем по дате изменения, товарные опции, мультикорзины и капча в формах.
- Старые шаблоны и клиентские доработки продолжали работать при поэтапных релизах.