Блог

Як створити єдиний стиль коду для 7 Frontend-проєктів за допомогою ESLint: досвід розробника

Мене звуть Вова Сінєвич, я Frontend Developer у продукті Livebeam від венчур-білдера SocialTech.

Напевно, більшість великих продуктів, у яких є не одна команда розробників і багато різних репозиторіїв, стикалися з неоднорідністю написання коду. Коли заходиш у проєкт і майже точно можеш сказати, хто з розробників писав ту чи іншу частину товару. Бо кожен розробник пише, як йому більше подобається, і немає єдиної системи координат, яка б задавала правила написання коду.

Ми також пройшли та можемо поділитися власним досвідом, як налаштувати та використовувати ESLint великому та зрілому проєкту, а також масштабувати його між репозиторіями.

Як працює ESLint

ESLint — інструмент для JavaScript, що дає змогу підтримувати якість коду та запобігати багам. З ним особливо легко працювати на маленьких проєктах: для цього достатньо додати цей пакет у залежності та пройти ініціалізацію, вибравши бажані налаштування.

Кожне правило можна конфігурувати за власними побажаннями

  • Рівень 0 вимикає правило
  • Рівень 1 ставить правило 'warning'
  • Рівень 2 'error'.

На рівень warning можна вивести менш критичні правила, дотримання яких, на вашу code style, бажано й необов’язково. Рівнем error можна користуватися, наприклад, як критерієм 'pass/fail' у pre-commit hook.

Яка виникла проблема у нас на продукті

Продукт Livebeam уже 8 років. Значну кількість цього часу ми активно додавали нові фічі та робили це різними командами розробників. На проєкті є кілька фронтенд-репозиторіїв: загальний UI для наших користувачів, мікросервіс чатів, кілька внутрішніх платформ, наприклад, модерації контенту, репозиторій платежів та інші.

У всіх репозиторіях уже під'єднано ESLint, але він працював неефективно. Тому що різні розробники проводять більшість часу в окремих репозиторіях, поступово підлаштовують їх під себе та зрештою створюють купу різних конфігурацій.

Тому вирішили, що нам нарешті потрібно навести лад і зробити єдиний code style.

Формулювання завдання: чому стиль коду має бути єдиним

Нашою метою було мати кодову базу, яку легко сприймати. Хороший код читається як хороша проза ©, і особливий внесок у це робить форматування коду. Відступи, крапки з комою, виділення у блоки мають вплив на те, як легко читати код.

Над продуктом ми працювали 4 командами розробників, які були залучені до роботи над продуктом і вносили то маленькі бізнес-зміни, то великі архітектурні. Купа правил були вимкнені, до того ж у нас проходила перевірка ESlint у CI/CD-платформі, тож кожен error означав, що деліверити не можна.

Ми прагнемо єдиної конфігурації, щоб наш код виглядав однорідно. Для цього нам потрібне єдине джерело правди, яким для нас стала окрема бібліотека зі конфігурацією ESLint, якою користуються всі наші проєкти.

Розв’язання задачі: правила написання коду

Від чого ми відштовхувалися перед початком роботи з ESint щодо введення єдиного стилю коду:

  • Узгодити між собою «хороші» правила написання коду, яким усі команди розробників згодні дотримуватися.
  • Чи не блокувати розроблення. Тобто не переводити частини продукту — теки, модулі, репозиторії, хоч би що це було — у стан «ремонтується, не чіпати» більш ніж на один день.
  • Чи не зупиняти продуктове розроблення. Ми не могли зробити паузу на кілька тижнів і переписати все, що потрібно. Бізнесу важливо, щоб ми продовжували втілювати його потреби в реальність.

Наші дії були такими:

  1. Почали з аналізу та візуалізації коду. Включали правило та перевіряли, наскільки воно нам підходить, і чи реально це виправити автоматично. Усі команди зібралися разом і порівнювали дві сторінки коду між собою. Хтось казав: «Такий вигляд краще» або «Давайте так не писати в один рядок».
  2. Запустили автофікс. Ми вибирали день, коли відкрито мінімум мердж-реквестів, і проганяли автофікс за одним із правил. Достатньо запустити автофікс, зробити мердж і готове. Коли йдеться про виправлення особливостей стилю коду, якщо щось вдало зблідло — найімовірніше, воно працюватиме. Важливо знати, що колеги, які на той момент відкрили власні реквести, потонуть у конфліктах.
  3. Зібрали 900 помилок і почали думати, як їх фіксувати. Підхід з автофіксом за одним із правил допоміг зробити частину роботи, але в результаті всі 900 помилок неможливо було виправити автоматично. І ми почали шукати інші варіанти виправлення.
  4. Почали виправляти все вручну. Ми спробували так зробити, але були частини системи, написані давно з нижчою якістю, ніж середня, за проєктом. Деякі помилки лінтер знаходив у частинах коду, написаного недостатньо прозоро — бракувало розуміння, як саме це працювало. Можна було би прийняти ризики та рефакторити такий код за умови, що він нам справді потрібний. Але оскільки наш продукт швидко змінюється та розвивається, у нас не було впевненості в тому, що ми не видалятимемо будь-який функціонал уже через місяць або змінюватимемо логіки в ньому. Це могло би стати марною працею, на додаток до ризиків, що несли за собою такий рефакторинг у крихких елементах системи.
  5. Знайшли рішення за допомогою плагіну suppress eslint errors, який залишає disable-next-line коментарі автоматично. Так, під час роботи у файлах, що містять такі коментарі, розробники можуть виправити помилки, якщо це посильно та раціонально. Ці коментарі автопрефіксуються на смак розробника. Тому можна зручно розділити наявні відключені правила на проєкті (або з’являються в майбутньому з волі розробників) від тих, що ми масово відключили автоматично. Це дає краще розуміння в очах коду, що читає.
  6. Як це виглядає. Наприклад, перший рядок каже: «Це правило відключили автоматично. Якщо ти вважаєш це правильним — виправи мене, згідно з нашими домовленостями про стиль коду. Якщо ти зустрів мене під час кодрева — не змушуй відповідального за мр виправляти мене, то це добровільна опція».

Тут навпаки — розробник цілеспрямовано відключив правило. Можна звертати додаткову увагу на кодреву, можна тикати git blame та шукати сліди злочину.

Отже, підсумуємо, як за допомогою ESLint дійти єдиного стилю коду на продукті:

  1. Спільними силами розробників вирішити, який має вигляд мати ваш код, обговорити правила.
  2. Конфігурувати ESLint у проєкті чи окрему бібліотеку (якщо кілька репозиторіїв).
  3. Запускати автофікс на простих правилах щоразу, переконуючись, що проєкт білиться й тести проходять.
  4. Використовувати плагін з автопрефіксером, щоби відключити всі правила, які не вдається виправити автоматично та позначити їх автоматично вимкненими. Так можна буде використовувати лінтер як pre-commit хуком локально, а також під час білду на CI/CD-платформі. Водночас володіти знаннями, де саме правило було відключено під час налаштування ESLint, а не після.
  5. Залишається виправляти такі винятки під час роботи з кодом, коли це можливо. А під час код ревью — хвалити колег, які це роблять, щоби мотивувати одне одного.

Звісно, це не єдиний підхід.

Ось щонайменше ще один:

  1. Слід повторити кроки 1—2 із флоу вище.
  2. Поставити всі правила до 'warning'-рівня — тепер із цим можна жити.
  3. Вибрати одне правило та перевести його на рівень 'error'.
  4. Позбавляємося всіх помилок у межах цього правила автофіксом або вручну. Якщо неможливо ні те, ні інше — додаємо disable-next-line коментар і примітку в стилі «виправте мене, коли дійдуть руки», так само як і з плагіном автопрефіксером.
  5. Повторюємо кроки 3–4, збільшуючи щоразу кількість правил у режимі помилок і зменшуючи кількість попереджень.

Це один із тих випадків, коли легше сказати, ніж зробити — у нас увесь процес зайняв близько року. Тому якщо ви також вирішите зробити єдиний code style на вашому продукті, сподіваюся, наш досвід буде вам корисний.