FastComments.com Blog

Fri Jan 31 2025
...

Завершено міграцію FastComments на TypeScript

! Ця стаття містить технічний жаргон

Що нового

У FastComments ми цінуємо статично типізовані мови. Більш конкретно, мені подобаються пристойні системи типів із швидкими компіляторами. FastComments почався з останніх - або без компілятора. Хоча ми мали дві служби, написані на сучасній Java протягом першого року, основні бібліотеки бекенду та фронтенду були написані на CJS JS, який працює на Node.

У підготовці до наступного десятиліття розробок ми мігрували найбільші компоненти FastComments на TypeScript.

Це включало міграцію понад 130 тис. рядків коду (100 тис. з цього - бекенд) через 1441 файл та виправлення понад 8000 помилок компіляції.

woooooo
Скріншот GitHub

Це було зроблено за два тижні.

Заморожування коду - Дякую

Я хотів би подякувати нашим клієнтам за терпіння щодо будь-яких затримок у виправленні помилок або випуску нових функцій, оскільки ми провели двотижневе заморожування коду для завершення цього оновлення. Дякую!

Виправлені помилки

Як ви можете уявити, ми виправили кілька помилок. В основному вони були пов'язані з виявленням спаму та кешуванням.

Руйнування змін

  • Всі API ендпоінти тепер повертають статус: 'failed' замість змішування "failed" і "failure" як значення статусу. "success" залишається незмінним.
  • Ми більше не будемо за замовчуванням використовувати першу конфігурацію віджета, якщо немає відповідності, натомість ми повернемо конфігурацію системи за замовчуванням.

Як це було?

Ми виявили, що, як зазвичай, багато інструментів в екосистемі NPM для допомоги в цьому завданні не працюють дуже добре. Тому ми використовували LLM для створення скриптів, щоб виконати більшу частину роботи. Наприклад, ми активно використовували JSDoc, щоб могли написати скрипти для взяття JSDoc і конвертації їх у інтерфейси typescript і типові визначення, а також правильно анотувати аргументи функцій та типи повернення. Ми також використовували ці скрипти для міграції з CJS на ESM, що включало переписування імпортів, експортів та виявлення загальних проблем на етапі виконання, таких як __dirname.

Чи я згадував про проблеми на етапі виконання?

Який TypeScript у 2025 році?

TypeScript є чудовою мовою для написання бізнес-логіки. Але Java все ще має кращий DevEx. Якщо Java, Go або Rust компілюються, найімовірніше, це буде працювати. З TypeScript я можу зробити щось на зразок:

console.log(__dirname);

... і це зкомпільується.

Але це не запуститься з сучасними es модулями. Ваш IDE навіть готовий автозавершити __dirname, а потім це зламається на етапі виконання. Відчувається, як Spring DI, але гірше.

Ви також можете зробити щось на зразок:

context.someImportantMethodToCall;

Тепер це "оператор". Це дійсний "оператор". На перший погляд ви можете подумати, що ми викликаємо someImportantMethodToCall, але ми не! Принаймні, мій IDE не попереджає про це, і компілятор також. Код просто нічого не зробить (якщо someImportantMethodToCall не є класовим getter, у такому випадку воно буде викликане автоматично...)

Виправлення таке:

context.someImportantMethodToCall();

Я думаю, ви, напевно, можете виявити це за допомогою чогось на зразок eslint і деякого правила "немає побічних ефектів", але тоді ви імплементуєте ще один великий набір бібліотек, які потрібно підтримувати, і тоді eslint має розбирати всю вашу кодову базу при кожному складанні, інструменти повільні тощо - ні дякую. Вплив на продуктивність через повільні інструменти, такі як eslint, був більш значним у моїй кар'єрі на попередніх роботах, ніж продуктивний "приріст", який я коли-небудь отримував від незначних виправлень/preventів eslint із пробілами тощо. Існують більш швидкі альтернативи тепер, що чудово.

TypeScript дуже приємний завдяки особливостям мови, таким як Pick<User, 'username', 'email'>. Це, в поєднанні з виведенням типів, забезпечує спосіб отримати типобезпечні результати запитів з бази даних для підмножок більших об'єктів без потреби визначати клас для кожної форми. Pick - це те, чому я здивований, що Scala не має. Типові об'єднання також дійсно класні.

Інкрементальні складання також працюють досить добре, ми лише збільшили час складання в CI приблизно на 5 - 10 секунд в середньому при складанні спільної бібліотеки, фронтенду та бекенду.

Хронологія розробки

Для тих, хто цікавиться, ось як виглядала наша прогресія:

  • Перший день: знайдено 5564 помилок у 362 файлах.
  • Другий день: знайдено 4034 помилок у 239 файлах.
  • Третій день: знайдено 3784 помилки у 191 файлі.
  • Четвертий день: знайдено 2974 помилки у 169 файлах.
  • П'ятий день: знайдено 3000 помилок у 171 файлі.
  • Шостий день: знайдено 2916 помилок у 165 файлах.
  • Сьомий день: знайдено 2618 помилок у 157 файлах.
  • Восьмий день: знайдено 2253 помилки у 109 файлах.
  • Дев'ятий день: знайдено 1605 помилок у 69 файлах.
  • Десятий день: знайдено 686 помилок у 53 файлах.
  • Одинадцятий день: тести одиниць бекенду пройдені.
  • Дванадцятий день: початок міграції фронтенду, 3118 помилок.
  • Тринадцятий день: знайдено 2172 помилки.
  • Чотирнадцятий день: знайдено 1224 помилки.
  • П'ятнадцятий день: знайдено 498 помилок.
  • Шістнадцятий день: всі помилки компіляції виправлені.
  • Сімнадцятий день: випущено. E2E тести пройшли. 30 хвилин простою під часunexpected runtime issues. :)

Майбутнє

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

Ви також можете очікувати, що наша бібліотека TypeScript на NPM покращиться, оскільки вона вже почала це робити, оскільки ми тепер вживаємо цю бібліотеку в нашому серверному та клієнтському коді.

Ми також найближчим часом випустимо згенеровані клієнтські SDK безпосередньо з серверного коду, що було основною причиною цього зусилля.

На завершення

Як і всі великі випуски, ми раді, що змогли знайти час для оптимізації, тестування та належного випуску цих змін. Дайте нам знати нижче, якщо ви виявите будь-які проблеми.

На зддоров'я!