Эра Build-Free: как запустить TypeScript в Node.js без сборки и компиляции
Я помню день, когда впервые настроил tsconfig.json. Это был 2016 год. Я потратил два часа на то, чтобы просто запустить сервер.
Два часа.
На опции. На пути. На то, почему outDir не туда складывает файлы. На Source Maps, которые не работали.
С тех пор я настроил сборку для TypeScript больше сотни раз. И каждый раз это выглядело примерно одинаково: ты открываешь документацию, копируешь конфиг, меняешь пару полей, запускаешь - и молишься.
А потом я попробовал Bun.
Ввел bun run index.ts - и оно просто... заработало.
Я сидел и смотрел в терминал минуту. Не верил. Перепроверил три раза. Это был TypeScript. Без сборки. Без tsconfig. Без папки dist. Просто запустился.
И я подумал: «Почему мы вообще терпели это десять лет?»
TypeScript появился в 2012 году. Его главная идея была гениальной: добавить типам в JavaScript.
Но вместе с этим появился обязательный этап.
Ты пишешь код:
//typescript
function calculate(price: number, discount: number): number {
return price - discount;
}Затем запускаешь компилятор, который удаляет типы:
//javascript
function calculate(price, discount) {
return price - discount;
}И только после этого Node.js запускает то, что получилось.
Ты написал одно. Запустилось другое.
И мы привыкли. Мы перестали замечать эту странность. Она стала нормой.
Но в последние пару лет я стал замечать, как эта норма начинает трещать по швам.
Сначала появились Deno и Bun. Они сказали: «Мы не будем ждать сборки. Мы просто запустим твой TypeScript».
И это работало. Мгновенно.
Я видел это. Я пробовал. Но думал: «Ну, это же экспериментальные рантаймы. В продакшене так нельзя».
А потом Node.js добавил --experimental-strip-types.
Я запустил:
//bash
node --experimental-strip-types app.tsИ оно заработало.
Я перепроверил.
Снова заработало.
В тот момент я понял: эпоха сборки для бэкенда заканчивается.
Что такое Type Stripping?
Это максимально простая идея.
Типы TypeScript не существуют во время выполнения. Интерфейсы, аннотации, обобщения - они нужны только компилятору. JavaScript-движок их не понимает.
Вот этот код:
//typescript
interface User {
id: number;
name: string;
}
function getUser(user: User): string {
return user.name;
}Type Stripping просто удаляет всё лишнее:
//javascript
function getUser(user) {
return user.name;
}Никакой компиляции. Никакой трансформации. Просто удаление типов.
При этом номера строк в файле не меняются. Ошибки возникают там же, где ты написал код.
Я не ожидал, что это изменение окажется настолько важным.
Когда говорят о Build-Free, все вспоминают скорость. Да, она есть. Она приятная. Но это не главное.
Главное - это то, что исчезает разрыв.
Раньше, когда ловил ошибку в продакшене, я видел что-то вроде:
TypeError: Cannot read properties of undefined
at dist/server.js:2417:18И начиналось путешествие. Где эта строка в исходниках? Какая карта исходников сейчас подключена? Правильно ли я пересобрал?
Теперь я вижу:
TypeError: Cannot read properties of undefined
at src/server.ts:58:14Прямо там, где я написал код.
Звучит как мелочь. Но когда ты ищешь баг в три часа ночи, эта мелочь стоит часов.
У Build-Free, конечно, есть ограничения.
Type Stripping не проверяет типы. Если передать строку вместо числа - оно запустится. Проверку нужно переносить в IDE и CI/CD.
И есть конструкции TypeScript, которые нельзя просто удалить. enum, parameter properties, некоторые декораторы - они требуют реальной компиляции.
Я столкнулся с этим на одном проекте. Использовал enum в нескольких местах. Пришлось переписать. Не критично, но стоит учитывать.
Но я заметил забавную вещь: чем больше я работал в Build-Free, тем проще становился мой код. Я переставал использовать конструкции, которые требуют компиляции. И мой TypeScript постепенно превращался в JavaScript с типами.
В хорошем смысле.
Я уже не представляю, как раньше терпел сборку.
Каждый новый проект теперь начинается с npm init. Пишу код. Запускаю. Проверяю.
Никаких конфигов. Никаких папок dist. Никаких Source Maps, которые не работают.
Просто код.
Я знаю, что фронтенд-разработка всё ещё требует сборки. Там другие задачи: оптимизация, tree-shaking, CSS. Vite и esbuild останутся.
Но бэкенд?
Микросервисы. API. CLI-утилиты. Внутренние инструменты.
Им не нужна сборка. Им нужен запуск. И проверка типов. И отладка.
Именно здесь Build-Free становится не экспериментом, а логичным выбором.
Я не знаю, станет ли Build-Free стандартом через пару лет.
Но я точно знаю, что npm run build больше не будет первым действием в моих бэкенд-проектах.
Я просто напишу код и запущу его.
Как когда-то запускал JavaScript.
Комментарии
Чтобы оставить комментарий, войдите в аккаунт.