Артур Ли и Аллен Кляйнер | Инженеры Pinterest, Core Experience

В Pinterest мы глубоко заботимся о продуктивности разработчиков. Мы хотим дать инженерам возможность работать быстро, сохраняя при этом высокое качество кода. Наша веб-база кода содержит более 4000 файлов JavaScript, каждый из которых строго линтуется с помощью eslint и комбинации правил Pinterest и Airbnb JavaScript lint rules. Мы считаем, что надежный и всеобъемлющий набор правил побуждает наших инженеров писать последовательно читаемый и поддерживаемый код, не попадая в синтаксические ловушки. Однако с растущей кодовой базой и большим набором правил время lint быстро превратилось в самый медленный путь в нашей сборке. Это начало замедлять процесс разработки, поэтому мы создали esprint, решение для быстрого линтинга как для CI, так и для сред разработки, которое мы открываем сегодня.

Многопоточный eslint

Самым большим узким местом, которое мы выявили, было то, что eslint работал в одном потоке. Мы использовали пакет worker-farm для распараллеливания прогонов eslint на нескольких ядрах. Затем мы взяли список файлов, которые требовали линтинга, и распределили их по нескольким рабочим процессам. Это дало нам немедленный выигрыш с ускорением примерно в 3 раза на 8-ядерной машине. Это было разумно, учитывая накладные расходы, связанные с запуском рабочих процессов в узле.

Это было значительным улучшением, особенно для наших работ по непрерывной интеграции (CI). Однако мы запускаем eslint каждый раз, когда файл изменяется в нашей среде разработки, поэтому инженеры регулярно получают отзывы о состоянии своего кода. Запуск процесса, потребляющего ресурсы ЦП, каждый раз при изменении файла будет слишком медленным, а также, возможно, замедлит более важные процессы, такие как webpack. Стало ясно, что нам нужно лучшее решение для среды разработки.

Вдохновленный потоком

Flow - это программа Facebook для проверки типов JavaScript. Хотя Flow не является средством проверки стиля, как eslint, ему также необходимо читать множество файлов, обрабатывать их и возвращать результаты. Flow делает это элегантно, выполняя большой объем работы параллельно во время своего первоначального запуска и поддерживая работу фонового сервера для кэширования результатов, так что последующие запуски выполняются практически мгновенно. Мы черпали вдохновение в архитектуре Flow, развернув фоновый сервер, который кэширует результаты lint в памяти и следит за изменениями в исходных файлах.

Представляем esprint

Мы назвали новый eslint cli esprint (произносится как E-S-sprint). Он использует многопоточный lint runner для линтинга файлов и запускает фоновый сервер для просмотра исходных файлов с помощью сторожа Facebook. Всякий раз, когда файлы меняются, watchman принимает это изменение, а esprint предварительно связывает эти измененные файлы. Выполнение команды esprint просто запрашивает у фонового сервера последний статус линта. Поскольку линнинг каждого дополнительного файла занимает очень мало времени, время выполнения esprint составляет порядка секунд, за исключением первоначального запуска.

В результате у нас есть быстрое решение для линтинга, подходящее как для CI, так и для сред разработки. Забегая вперед, мы планируем повысить надежность фонового сервера, а также производительность, используя такие методы, как повторное использование экземпляров движка eslint. Вы можете найти код для бета-версии на GitHub. Мы приветствуем любые вопросы и запросы на вытягивание!

Благодарности: спасибо команде Core Experience и нашим веб-инженерам за тестирование и отзывы.