vercel-labs/scriptc — TypeScript-to-Native Compiler
scriptc — TypeScript를 네이티브 실행 파일과 WebAssembly로 컴파일하는 도구
scriptc는 TypeScript와 JavaScript를 타입 검사한 뒤 네이티브 실행 파일, WebAssembly, C와 LLVM IR 등으로 내보내는 실험적 컴파일러입니다. 정적으로 컴파일할 수 없는 코드는 진단으로 표시하며, npm 패키지나 any 타입 코드는 --dynamic 옵션으로 QuickJS 엔진을 포함해 실행 파일에 담습니다.
- 주제
AI 요약
scriptc는 TypeScript 컴파일러로 파싱과 타입 검사를 수행하고, TypeScript와 JavaScript를 여러 단계의 컴파일 결과물로 변환합니다. Node.js 24 이상이 필요하며, 프로젝트는 실험 단계로 macOS, Linux, Windows와 WASI Preview 1을 대상으로 합니다.
출력 형식과 빌드
컴파일 결과는 타입 정보를 담은 IR, 읽기 쉬운 C, 텍스트 LLVM IR, 네이티브 어셈블리와 오브젝트 파일, 실행 파일, WebAssembly 모듈입니다. --emit=ir|c|llvm은 Node.js만으로 실행하며, clang이나 링커를 부르지 않습니다. macOS·Linux·Windows의 지원 환경에서는 패키지에 포함된 플랫폼 헬퍼로 어셈블리와 오브젝트 파일도 만듭니다.
일반 LLVM 실행 파일 빌드에는 플랫폼 링커 드라이버와 SDK 또는 sysroot가 필요합니다. 다만 생성한 C 코드나 런타임 C 코드를 직접 컴파일하지 않습니다. scriptc의 헬퍼와 사전 컴파일된 런타임 묶음을 사용하며, SCRIPTC_LINKER로 링커 드라이버를 지정합니다. 명시적인 C 출력, LLVM 대체 경로, --sanitize에는 C 컴파일러가 필요합니다. 생성된 실행 파일은 Node.js 없이 실행됩니다.
--emit=obj는 독립 라이브러리가 아니라 재배치 가능한 프로그램 오브젝트를 만듭니다. 이 파일은 scr_* 런타임 심볼을 참조하며 scr_runtime_abi_v1 표시가 필요합니다. 외부에서 오브젝트를 소비하는 기능은 실험 단계입니다. --print=native-link-info를 지정하면 대상 플랫폼, 진입점, 런타임 소스 묶음, 시스템 라이브러리, FFI 입력과 ABI 표시를 담은 버전 관리 JSON 레시피를 출력합니다. 자체 포함 아카이브가 필요하면 scriptc build --lib --profile ...을 사용합니다.
정적 컴파일과 동적 코드
지원하는 Node API는 네이티브 런타임으로 컴파일합니다. 예제에는 node:http 서버가 있으며, 요청 경로를 JSON으로 반환합니다. scriptc coverage는 정적으로 컴파일 가능한 문장 수와 비율을 보여주고, 동적이거나 지원하지 않는 지점마다 코드가 붙은 진단을 제공합니다. 정적으로 처리할 수 없는 코드가 있으면 이를 진단으로 알립니다.
npm 패키지나 any 타입 코드가 필요하면 --dynamic을 지정합니다. 이 경우 QuickJS-NG를 실행 파일에 명시적으로 포함합니다. 예제에서는 picocolors를 포함해 색상 출력 프로그램을 빌드합니다. 결과 실행 파일은 실행 중 node_modules를 읽지 않습니다.
WebAssembly와 지원 경계
WASI 및 다른 교차 컴파일 대상에는 Zig가 필요합니다. Zig의 cc 하위 명령을 선택할 때 SCRIPTC_CC=zigcc를 설정하고, WASI 대상은 SCRIPTC_TARGET=wasm32-wasi로 지정합니다. WASI Preview 1에서는 async/await, 프라미스, 제너레이터, 타이머, 표준 입력 이벤트와 파일 시스템 API 등을 지원합니다. 네트워크 소켓과 fetch, 자식 프로세스, OS 신호, 파일 시스템 감시처럼 WASI Preview 1이 제공하지 않는 기능은 링크 전에 SC3002 진단으로 거부합니다. sanitizer 빌드, 네이티브 FFI, 라이브러리 아카이브 모드도 해당 대상에서 지원하지 않는다고 안내합니다.
테스트와 빌드 환경
저장소의 테스트 코퍼스는 각 프로그램을 Node.js와 컴파일된 네이티브 바이너리에서 실행한 뒤 표준 출력, 표준 오류, 종료 코드를 바이트 단위로 비교합니다. 전체 테스트에는 AddressSanitizer 실행과 런타임 참조 카운트 검사도 포함됩니다. 일반 워크스페이스 빌드에는 로컬 LLVM 설치가 필요하지 않지만, 네이티브 헬퍼와 런타임 묶음을 다시 만들려면 CMake, Ninja, 고정 버전 LLVM 22 개발 패키지가 필요합니다.
원문: GitHub / 번역·요약: Trawling