Изолированные объявления TypeScript: ускорение сборки монорепозитория
Сборки монорепозиториев часто замедляются из-за того, как TypeScript обрабатывает файлы объявлений. По умолчанию TypeScript анализирует каждую цепочку импортов, прежде чем создать хотя бы один файл .d.ts. Это создает длинную очередь, в которой пакеты вынуждены ждать друг друга.
Это можно исправить с помощью флага --isolatedDeclarations.
Этот флаг позволяет выполнять сборку параллельно. Вместо ожидания зависимостей каждый пакет генерирует свои собственные объявления независимо. Команды отмечают ускорение сборки в 3–15 раз.
Проблема:
TypeScript обычно выводит типы через границы модулей. Если пакет A зависит от пакета B, компилятор должен полностью разрешить B, прежде чем приступить к A. В большом монорепозитории большинство пакетов простаивают, пока компилятор обрабатывает их по очереди.
Решение:
Флаг --isolatedDeclarations меняет правила. Он требует явного написания аннотаций типов для всего, что вы экспортируете.
Компромисс:
Объем кода увеличится. Вам придется вручную добавлять типы возвращаемых значений функциям и типы константам. Вы больше не можете полагаться на то, что компилятор сам угадает эти типы на основе вашего кода.
Результат:
Поскольку каждый экспорт имеет четко определенный тип, компилятору не нужно изучать другие пакеты, чтобы понять их. Он может обрабатывать каждый пакет одновременно.
Реальные результаты:
- Монорепозиторий с 18 пакетами сократил время сборки с 47 секунд до 3,2 секунд.
- В монорепозитории с 32 пакетами производительность в CI-конвейерах выросла в 8 раз.
- Производительность масштабируется вместе с количеством ядер вашего процессора. Больше ядер — больше пакетов собираются одновременно.
Как перейти на этот режим:
- Включите флаг в корневом
tsconfig.jsonи в конфигурации каждого пакета. - Используйте флаг
"composite", чтобы разрешить ссылки на проекты (project references). - Добавляйте явные типы возвращаемых значений к экспортируемым функциям:
// До
export function add(a: number, b: number) {
return a + b;
}
// После
export function add(a: number, b: number): number {
return a + b;
}
- Добавляйте явные типы к экспортируемым константам:
// До
export const SETTINGS = { port: 3000 };
// После
export const SETTINGS: { port: number } = { port: 3000 };
Если вы не добавите эти типы, компилятор выдаст ошибку. Это гарантирует, что ваши типы будут детерминированными и быстрыми.
