Всем привет! Продолжим цикл историй про то, чем занимается команда Web Core в ДомКлик. В предыдущей статье мы рассказывали, как создаем дизайн-систему. А в этот раз хотелось бы поделиться историей разработки системы мониторинга качества frontend-проектов — Front Radar. У нас в компании много проектов, которые создаются большим количеством команд, и в связи с этим потребовалось проверять актуальность проектов и выявлять проблемные места, которые негативно влияют на клиентский опыт.

Цели, которые мы преследовали при реализации этого проекта:

  • оценивать актуальность проекта (своевременное обновление зависимостей);

  • проверка на уязвимости;

  • проверка легальности использования зависимостей (проверка лицензий);

  • сбор статистики по размерам проекта;

  • сбор статистики по таким параметрам, как Perfomance, SEO, Accessibility.

Front Radar представляет из себя REST-сервис, который содержит множество микросервисов и запускает их в зависимости от вызванного API и набора параметров. Набор этих микросервисов сегодня такой:

  • Dependencies license checker

  • Dependencies update checker

  • Dependencies safety checker

  • Bundle sizes checker

  • NPM sizes checker

  • Lighthouse

  • W3C Validator

Наш сервис будет запускаться для двух этапов проверок: как блокирующий Quality Gate в pipeline на этапе сборки, и второй этап — после успешного деплоя.

Встраиваем Front Radar в Pipeline как quality gate
Встраиваем Front Radar в Pipeline как quality gate

Первый этап проверок запускается через стандартный web-hook со таким набором параметров: идентификатор проекта, версия релиза, URL репозитория и объект данных с информацией о размере файлов, необходимых для функционирования веб-клиента (для сбора аналитики в Bundle sizes checker). Этого нам достаточно, чтобы стянуть проект из репозитория, установить зависимости и проанализировать проект каждым из микросервисов. Результаты анализа мы сохраняем в БД, где ключом будет являться ID проекта. Таким образом у нас сохраняется вся статистика, и от релиза к релизу мы можем оценивать состояние нашей кодовой базы.

Dependencies license checker

Проверяет, что в проектах мы используем библиотеки с лицензиями, разрешающими свободное использование в коммерческой деятельности. Под капотом сервиса мы используем библиотеку license-checker, предварительно установив зависимости для проекта, который стянули из репозитория. После проверки утилита нам отдает ответ в формате:

{
  'resolve-url@0.2.1': {
    licenses: 'MIT',
    repository: 'https://github.com/lydell/resolve-url',
    publisher: 'Simon Lydell',
    path: '/Users/royroev/WebstormProjects/package-stats/temp/project-5/node_modules/resolve-url',
    licenseFile: '/Users/royroev/WebstormProjects/package-stats/temp/project-5/node_modules/resolve-url/LICENSE'
  },
  'resolve@1.12.0': {
    licenses: 'MIT',
    repository: 'https://github.com/browserify/resolve',
    publisher: 'James Halliday',
    email: 'mail@substack.net',
    url: 'http://substack.net',
    path: '/Users/royroev/WebstormProjects/package-stats/temp/project-5/node_modules/resolve',
    licenseFile: '/Users/royroev/WebstormProjects/package-stats/temp/project-5/node_modules/resolve/LICENSE'
  },
  ...
}

Хочется отметить, что утилита собирает информацию не только по зависимостям первого уровня, которые указаны в package.json, но и обходит всё дерево зависимостей.

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

Dependencies update checker

Собирает статистику по обновлению зависимостей. Своевременное обновление используемых позволяет поддерживать проект в актуальном состоянии. Сообщества с каждым релизом улучшают свои библиотеки, уменьшают их вес, устраняют уязвимости и баги, которые могут навредить вашему проекту. Также этот модуль дает представление об обновлении компонентов UI Kit , так как команда Web Core каждый день улучшает свои продукты и хочет, чтобы другие команды их обновляли. Если кто-то этого не делает, мы должны выявить причину, мешающую обновиться, и устранить её.

Также в этом модуле мы проверяем, зафиксированы ли версии библиотек, а именно проверяем наличие lock-файлов. Это необходимо для того, чтобы при сборке проекта команда не столкнулась с такими проблемами в зависимостях, как наличие уязвимостей, изменение лицензионного соглашения, breaking changes и банальными багами. Подробнее ознакомиться с тем, зачем это нужно, можно в статье нашего сотрудника.

Dependencies safety checker

Проверяет зависимостей на уязвимости. Мы используем несколько проверок npm audit и обращаемся к базе уязвимостей Node Security Project. Ознакомиться с тем, как работает npm audit, можно в этой статье. Для нас этот сервис является блокирующим: если он находит в зависимостях библиотеку с уязвимостью, то мы вынуждены заблокировать публикацию проекта.

Bundle sizes checker

Собирает статистику по размеру собранных бандлов для веб-клиента. Для этого мы получаем в пришедшем web-hook объект данных, который содержит информацию о размере всех файлов в проекте, необходимых для его функционирования. Эти данные собираются в CI/CD с помощью рекурсивного обхода папки с собранным проектом. Пример объекта:

{
	sumSize: 40355,
  sumSizeZip: 10285,
  files: [
  	{
    	name: 'main.js',
      size: 11022,
      sizeZip: 4033,
    },
    {
    	name: 'vendors.js',
      size: 22142,
      sizeZip: 8012,
    },
    ...
  ]
}

Эти данные мы также сохраняем в БД для формирования статистики по проекту. Теперь мы можем проанализировать от релизу к релизу, как проект прибавляет или убавляет в весе, и если при текущем релизе проект стал весить значимо больше, то мы помечаем такую сборку флагом «требует внимания».


Второй этап проверок запускается непосредственно после деплоя проекта (для веб-клиентов это публикация проекта в production-среде, для npm-пакетов — публикация в npm registry). Как и на первом этапе, срабатывает web-hook, но уже с другим набором параметров: идентификатор проекта, массив адресов страниц проекта (для веб-клиента), название пакета в registry (для npm-пакета).

NPM sizes checker

Собирает статистику по размеру собранных npm-пакетов. В нашей компании есть свой приватный bundle registry, в котором мы публикуем свои библиотеки для дальнейшего переиспользования в других командах. И, конечно же, хотелось бы собирать статистику по размеру таких пакетов. В этом сервисе мы генерируем файл index.js (entryFile) с импортом нашей библиотеки, устанавливаем её командой npm i $package-name и собираем с помощью webpack наш entryFile. После успешной сборки мы получаем JSON-объект stats, в котором содержатся данные о размере JS- и CSS-файлов. На основе исторических данных мы можем формировать статистику и выявлять положительную или отрицательную динамику.

Lighthouse

Есть несколько способов мониторить ваш веб-клиент с помощью Lighthouse:

  1. С помощью PageSpeed API (настройка подробно описана в этой статье). Запускается по графику, не связано никак с вашим CI/CD, поэтому нет никакой привязки к релизу.

  2. С помощью lighthouse-ci. Очень удобный инструмент с массой настроек. Можно запустить сценарий на Puppeteer, если ваша страница, к примеру, закрыта под авторизацию. Способ подойдет вам, если собираете проект одним из перечисленных инструментов для CI/CD: GitHub Actions, Travis CI, Circle CI, GitLab CI, Jenkins (на основе Ubuntu), Google Cloudbuild. Если у вас что-то иное, придется покопаться в чужом коде или перейти к пункту 3.

  3. Написать свой сервис на основе сервера node.js и npm-библиотеки Lighthouse, со своими правилами, настройками и кастомными сценариями.

Мы выбрали 3 пункт, потому что нам хотелось более тонкой настройки сервиса и возможности запускать как при публикации новой версии проекта, так и по расписанию. После публикации веб-клиента в production-среде мы запускаем проверку массива пришедших в web-hook урлов с помощью Lighthouse. Сервис представляет из себя сервер node.js, на котором мы сначала запускаем chrome-launcher; если надо проанализировать веб-клиент, закрытый под авторизацию, то запускаем сценарии авторизации (наши автотесты), а затем запускаем проверку страниц с помощью библиотеки Lighthouse.

const chromeFlags = [
    '--disable-gpu',
    '--headless',
    '--no-zygote',
    '--no-sandbox',
  	'--disable-dev-shm-usage',
];

const config = {
  "extends": "lighthouse:default",
  "settings": {
    "emulatedFormFactor": "mobile",
    "useThrottling": true
  }
};

const chrome = await chromeLauncher.launch({ chromeFlags });

const flags = {
  port: chrome.port,
  output: 'json',
  'max-wait-for-load': 500000,
};

const result = await lighthouse(url, flags, config);

/*
result = 

{
  "performance-score": 83,
  "accessibility-score": 98,
  "best-practices-score": 100,
  "seo-score": 100,
  "pwa-score": 100,
  "firstContentfulPaint": 2341,
  "firstMeaningfulPaint": 2341,
  "largestContentfulPaint": 3736,
  "firstCPUIdle": 4951,
  "interactive": 5101,
  "speedIndex": 2341,
  "estimatedInputLatency": 13,
  "totalBlockingTime": 221,
  "maxPotentialFID": 210,
  "cumulativeLayoutShift": 0.009377760145399306,
  "cumulativeLayoutShiftAllFrames": 0
}

*/

Мы знаем, что проверки Lighthouse могут отличаться в зависимости от разных условий выполнения проверок, поэтому мы запускаем 5 проверок для каждой страницы и вычисляем среднее значение по каждому показателю. После чего агрегируем и сохраняем данные в БД и пытаемся создать инфографику, понятную нашим командам.

Также с каждым релизом мы сохраняем отчет Lighthouse, в котором отображены результаты и рекомендации по улучшению сайта.

W3C checker

Представляет из себя NodeJS-приложение, которое использует библиотеку html-validator. Мы получаем в формате JSON данные об ошибках и предупреждениях, которые суммируем для отслеживания динамики от релиза к релизу, а также в формате HTML для отображения рекомендаций разработчикам.

Заключение

Все показатели влияют на клиентский опыт использования наших продуктов, поэтому на основе всех собранных метрик мы даем рекомендации проектам по улучшению кодовой базы и выявляем все отклонения от лучших практик в мире web-разработки. Команды стараются поправить отклонения в рамках технической квоты.

Мы не собираемся останавливаться на перечисленных проверках, в планах у нас подключения дополнительных систем анализа наших web-проектов — Favicon Checker, SEO Checker, Link Checker, CSS Validator, CSS Stats. Надеюсь, что статья была вам полезна и вы организуете у себя подобную систему мониторинга. Конечно же, жду вас в комментариях, всегда буду рад ответить на ваши вопросы и замечания.