Vercel представила Scriptc, компилятор TypeScript в нативные бинарники

Vercel представила Scriptc, компилятор TypeScript в нативные бинарники

Scriptc, проект Vercel Labs для компиляции обычного TypeScript в самодостаточные нативные исполняемые файлы. Авторы подчёркивают, что для статически скомпилированной программы не нужны Node.js, V8 или иной JavaScript-движок: в примере бинарник с вычислением чисел Фибоначчи занимает 178 КБ и запускается примерно за 2 мс. Исходный код не требует аннотаций, отдельного диалекта или изменений: проверка типов выполняется настоящим компилятором TypeScript, а заявленная цель, байт-в-байт совпадающее с Node.js поведение там, где код компилируется.

Компилятор анализирует конструкции по отдельности и делит результат на три явно обозначенных режима. Статически компилируемый код становится нативным и является режимом по умолчанию. Для фрагментов, которые нельзя статически обработать, есть опция --dynamic: в бинарник встраивается quickjs-ng размером около 620 КБ; она предназначена, в частности, для поставляемого JavaScript из npm-зависимостей и значений с типом any. Остальное отклоняется с кодом ошибки, указанием места в коде и, как правило, подсказкой по переписыванию; проект обещает не выполнять молчаливую неверную компиляцию.

В описании заявлена поддержка широкого набора возможностей TypeScript, стандартной библиотеки и Node.js: классов, замыканий, обобщений, async/await, исключений, строк, массивов, Map и Set, JSON, Buffer, fs, process, child_process, сетевых модулей, HTTP/HTTPS/TLS, fetch и части веб-стандартов. npm-пакеты в динамическом режиме разрешаются по алгоритму Node.js, проверяются по поставляемым .d.ts и встраивают JavaScript при сборке, поэтому готовый бинарник не читает node_modules во время работы.

Надёжность совместимости Scriptc проверяет двумя обязательными механизмами при каждом изменении. Дифференциальный набор из более чем 800 тестов запускается и под Node.js, и в нативном бинарнике; stdout, stderr и код завершения должны совпасть байт в байт. Отдельный прогон с AddressSanitizer и аудитом подсчёта ссылок ловит утечки и обращения к освобождённой памяти. Создатели признают несколько десятков документированных расхождений, в основном вокруг внутренних деталей времени выполнения и свойств объектов ошибок.

Ключевые факты

  • Scriptc компилирует TypeScript в нативные исполняемые файлы без Node.js, V8 и JavaScript-движка в статическом режиме.
  • Компилятор использует настоящий TypeScript для проверки типов и сообщает, какие конструкции статически компилируются, запускаются динамически или отклоняются.
  • Опция --dynamic встраивает quickjs-ng размером около 620 КБ для JavaScript из npm-зависимостей и значений с типом any.
  • Совместимость с Node.js проверяется дифференциально на более чем 800 тестах; отдельный прогон с AddressSanitizer проверяет память.
  • Основная платформа, macOS arm64; бинарники для Linux и Windows собираются кросс-компиляцией и проверяются отдельными тестами.

Почему это важно

Scriptc предлагает другой способ доставки программ на TypeScript: вместо зависимости от установленного Node.js можно получить самодостаточный нативный файл. Проект делает акцент не только на скорости и размере, но и на проверяемом совпадении поведения с Node.js.

Кому это важно

Инструмент ориентирован на разработчиков TypeScript, которым нужны автономные утилиты, серверы или программы с быстрым стартом. Он также касается проектов с npm-зависимостями: их JavaScript можно встроить в файл через динамический режим.

Как это применить

Установка выполняется командой npm install -g scriptc; для сборки нужен clang. Команда scriptc coverage показывает долю статически компилируемого кода и конкретные блокирующие конструкции, а scriptc build создаёт бинарник. Если часть программы требует JavaScript-исполнения, её можно собрать с --dynamic.

Можно ли доверять

Авторы описывают два постоянных гейта: более 800 программ сравниваются между Node.js и нативным результатом по stdout, stderr и коду завершения, а отдельная линия тестов запускает корпус под AddressSanitizer и аудитом подсчёта ссылок. При этом проект прямо указывает на несколько десятков документированных расхождений.

Риски и подводные камни

Не весь TypeScript обязательно попадёт в статический режим: Scriptc может потребовать --dynamic либо отклонить конструкцию с диагностикой. Динамический режим добавляет встроенный JavaScript-движок примерно на 620 КБ. Заявленная первичная платформа, macOS arm64, а Linux и Windows пока зависят от кросс-компиляции.