Строим систему для мониторинга качества frontend-проектов

bfa286cc0d98de2eef57a8b82ea3aeec.jpg

Всем привет! Продолжим цикл историй про то, чем занимается команда 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 каждый день улучшает свои продукты и хочет, чтобы другие команды их обновляли. Если кто-то этого не делает, мы должны выявить причину, мешающую обновиться, и устранить её.

fcb74cc105b15978fed28b0e186d6128.png

Также в этом модуле мы проверяем, зафиксированы ли версии библиотек, а именно проверяем наличие 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-файлов. На основе исторических данных мы можем формировать статистику и выявлять положительную или отрицательную динамику.

bca23276f83ee7b30b19a5949188814c.png

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 проверок для каждой страницы и вычисляем среднее значение по каждому показателю. После чего агрегируем и сохраняем данные в БД и пытаемся создать инфографику, понятную нашим командам.

4165524caf3b1b4ff3571243ce59ead5.png

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

00c836be81e020bbb0bfc138e0eebf55.png

W3C checker

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

97f83c555d35df8b11079b74c41c83ca.png

Заключение

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

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

© Habrahabr.ru