FastComments.com Blog

Fri Jan 31 2025
...

Завершена миграция FastComments на TypeScript

! Эта статья содержит технические термины

Что нового

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

В подготовке к следующему десятилетию разработки мы мигрировали крупнейшие компоненты FastComments на TypeScript.

Это потребовало миграции более 130 тысяч строк кода (из которых 100 тысяч — это бэкенд) по 1441 файлу и исправления более 8000 ошибок компиляции.

вауууу
Скриншот GitHub

Эта работа заняла две недели.

Заморозка кода - Спасибо

Я хотел бы поблагодарить наших клиентов за понимание задержек в исправлении ошибок или релизах функций, поскольку мы провели двухнедельную заморозку кода для завершения этого обновления. Спасибо!

Исправленные ошибки

Как вы можете представить, мы исправили множество ошибок. Они в основном касались обнаружения спама и кэширования.

Ломаем изменения

  • Все API-эндпоинты теперь возвращают status: '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, было более значительным в моей карьере в прошлых работах, чем "прирост" продуктивности, который я когда-либо получил от мелочей, которые 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 минут простоя во время неожиданных проблем во время выполнения. :)

Будущее

Мы сделали это, чтобы поддерживать разработку в следующем десятилетии. Система теперь достаточно велика, чтобы разработка с системой типов была быстрее, чем без нее.

Вы также можете ожидать улучшений нашей библиотеки TypeScript на NPM, так как она уже начала улучшаться, поскольку мы теперь используем эту библиотеку в нашем серверном и клиентском коде.

Скоро мы также выпустим сгенерированные клиентские SDK непосредственно из серверного кода, что было основным мотивом этой работы.

В заключение

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

Удачи!