تصور کنید ابزارهای خط فرمان شما بهجای چند ثانیه، در کمتر از ۳ میلیثانیه اجرا شوند. اگر از کندی راهاندازی برنامههای مبتنی بر جاوااسکریپت خسته شدهاید، زمان آن رسیده که با مفهوم «صفر-زمان-اجرا» آشنا شوید. یک باینری بومی برای تایپاسکریپت اکنون در حدود ۲.۴ میلیثانیه شروع به کار میکند و بهطور مؤثر جریمهٔ سنگین راهاندازی سرد را در اکوسیستم جاوااسکریپت پاک میکند.
Vercel Labs در ۲۶ ژوئیه ۲۰۲۶ ابزار scriptc را معرفی کرد تا مسیری برای تبدیل تایپاسکریپت (TypeScript) به باینریهای بومی (Native Binaries) فراهم کند. این رویکرد، نیاز به Node.js و موتور V8 را بهطور کامل حذف میکند و جریمهٔ سنگین راهاندازی سرد (Cold Start) — یعنی همان تأخیری که شبیه به گرم شدن موتور ماشین در صبحهای زمستانی است تا برنامه آماده به کار شود — را بهطور مؤثر از بین میبرد.
این تغییر در زمانی رخ میدهد که توسعهدهندگان بهطور فزایندهای خواستار عملکرد زبانهای سیستمی هستند، بدون اینکه بخواهند بهرهوری تایپاسکریپت را رها کنند. scriptc با تکیه بر روند کامپایل بومی برای زبانهای سطح بالا — مشابه آنچه Pon برای پایتون ۳.۱۴ هدف قرار داده بود — با تایپاسکریپت نه بهعنوان یک پوشش برای جاوااسکریپت، بلکه بهعنوان زبانی با قابلیت تحلیل استاتیک برخورد میکند.
طبق مستندات گیتهاب این پروژه، scriptc از یک مدل اجرای سهلایه برای تضمین صحت کد استفاده میکند:
- کامپایل استاتیک: حالت پیشفرض که در آن کد مستقیماً از طریق LLVM یا یک بکاند C به کد ماشین تبدیل میشود. این تنها حالتی است که اجرا میشود، مگر اینکه کاربر صراحتاً گزینه دیگری را انتخاب کند.
- اجرای پویا: برای مدیریت عناصری که استاتیک نیستند، مانند وابستگیهای npm یا کدهایی با نوع
anyاز یک موتور جاسازیشده به نام quickjs-ng (با حجم حدود ۶۲۰ کیلوبایت) از طریق پرچم--dynamicاستفاده میکند. هر مقداری که از بخش پویا به کد استاتیک بازگردد، در زمان اجرا اعتبارسنجی میشود؛ اگر نوع دادهای دروغین باشد، یک خطایTypeErrorقابل مدیریت پرتاب میشود تا از فساد حافظه جلوگیری شود. - رد شده: کدهایی که بهصورت ایمن قابل تبدیل به کد ماشین نیستند، با کدهای خطای مشخص علامتگذاری میشوند (بهعنوان مثال، کد SC1090 برای پارامترهای اختیاری بهعنوان مقدار، و SC2020 برای
Promise.reject). این خطاها همراه با یک قاب کد (code frame) و راهنماییهایی برای بازنویسی ارائه میشوند.
بر اساس بررسیهای فنی روی سختافزارهای سری M اپل، باینریهای تولید شده توسط scriptc در حالت استاتیک تنها ۱۷۰ تا ۲۰۰ کیلوبایت حجم دارند؛ در حالی که برنامههای Node.js (SEA) معمولاً بین ۶۰ تا ۱۰۰ مگابایت هستند. حتی با استفاده از وابستگیهای جاسازیشده از طریق --dynamic نیز حجم باینریها در حدود ۳ مگابایت باقی میماند. مصرف حافظه (RSS) نیز به ۱ تا ۴ مگابایت کاهش یافته که در مقایسه با ۶۷ تا ۱۱۶ مگابایت مورد نیاز در محیطهای استاندارد Node.js، یک کاهش خیرهکننده است.
قابلیتهای کلیدی و امنیت
به نقل از تیم توسعه، این کامپایلر از سطح گستردهای از زبان پشتیبانی میکند؛ از جمله کلاسها با ارثبری تکگانه و دیسپچ پویا (Dynamic Dispatch) واقعی که در صورت اثبات ایمنی، به صورت devirtualized در میآیند. همچنین از جنریکها (که به صورت monomorphized پیاده شدهاند) و async/await روی فیبرهای استکدار با زمانبندی دقیق مشابه جاوااسکریپت پشتیبانی میکند. این ابزار یک حلقه رویداد (Event Loop) بدون وابستگی و یک استک سرور بومی شامل net و http و https و tls (از طریق نسخه داخلی mbedTLS) و همچنین dgram و dns و fs.watch را پیادهسازی کرده است.
جزئیات پشتیبانی از زبان و کتابخانهها شامل موارد زیر است:
- ویژگیهای زبانی: بستارها (Closures) با معناشناسی کپچر جاوااسکریپت، اتحادیههای تشخیصدادهشده (Discriminated Unions) بهعنوان مقادیر تگدار، استثناها (Exceptions) همراه با بلوک
finally، ساختارهای Destructuring، Spread و Template Literals. - کتابخانه استاندارد: رشتهها با معناشناسی دقیق UTF-16، آرایهها/Maps/Sets با ترتیب دقیق مشابه جاوااسکریپت، و JSON با کستهای اعتبارسنجیشده در زمان اجرا.
- رابط Node API: پشتیبانی از
fs(همگام و Promise)،path(پورت دقیق بایت-به-بایت)،processوchild_processبا استریمهای لولهکشی شده (piped streams)،osوcryptoوurl/URL. - زیرمجموعه وب: پیادهسازی
fetchو جریانهای WHATWG، Headers و AbortSignal (شاملAbortSignal.timeout) بدون تکیه به libcurl یا وابستگیهای HTTP سیستم.
برای جلوگیری از فساد حافظه، scriptc از دو مسیر نظارتی سختگیرانه استفاده میکند. اول، تستهای تفاضلی تضمین میکنند که بیش از ۸۰۰ برنامه نمونه، خروجیشان با Node.js بهصورت بایت-به-بایت یکسان باشد؛ این شامل فرمتبندی اعداد با کوتاهترین مسیر بازگشت (shortest-roundtrip) است که در برابر یک میلیون عدد double اعتبارسنجی شده است. دوم، یک مسیر ایمنی حافظه با استفاده از AddressSanitizer، شمارش مراجع (reference counts) را حسابرسی کرده و خطاهای use-after-free را در زمان ساخت شناسایی میکند.
معماری و پیادهسازی
خط لوله کامپایل از یک جریان سختگیرانه پیروی میکند: کد تایپاسکریپت ابتدا از طریق API مربوط به tsc تجزیه و بررسی نوع میشود، سپس به یک نمایش میانی (IR) تایپشده تبدیل شده و در نهایت به بکاند C یا LLVM سپرده میشود تا فایل اجرایی نهایی تولید شود. این IR بهعنوان تنها رابط بین فرانتاند و بکاندها عمل میکند.
زمان اجرای C مقادیر با شمارش مرجع (refcounted) را با یک جمعکننده چرخه (cycle collector) مدیریت میکند و برای حلقه رویداد از kqueue بهره میبرد. واحدهای ویژگی بهصورت link-gated هستند، به این معنی که باینری نهایی فقط کدهایی را شامل میشود که واقعاً در برنامه استفاده شدهاند. برای نصب، این ابزار به clang نیاز دارد (که در Xcode Command Line Tools گنجانده شده است). اگرچه macOS arm64 پلتفرم اصلی است، اما باینریهای لینوکس و ویندوز نیز از طریق کامپایل متقاطع پشتیبانی شده و توسط مسیرهای جداگانهی تست تفاضلی تأیید شدهاند.
راهکارهای جایگزین برای توسعهدهندگان
برای نیازهای با کارایی بالا، این ابزار تابع comptime(() => ...) را فراهم میکند که اجازه میدهد کدهای تایپاسکریپت در زمان ساخت در یک VM ایزوله اجرا شوند تا مقادیر ثابت (literals) مستقیماً در باینری جایگذاری (bake) شوند. همچنین قابلیت Native FFI (از طریق --ffi) برای فراخوانی مستقیم ABIهای C فراهم شده است که به توسعهدهندگان اجازه میدهد آرشیوهای تعریفشده در مانیفست و کتابخانههای سیستم را از طریق یک مرز صریح و محدود به طول (length-delimited) متصل کنند.
این پیشرفت فرض بنیادین درباره نیاز تایپاسکریپت به یک محیط اجرای سنگین برای ابزارهای CLI یا توابع لبه (Edge Functions) را تغییر میدهد. با انتقال «هزینه» موتور از زمان اجرا به زمان ساخت، scriptc اکنون میتواند در محیطهای حساس به سرعت، مستقیماً با Zig، Go و Rust رقابت کند.
برای یک توسعهدهنده معمولی، این به معنای توانایی ارسال یک باینری واحد و بسیار کوچک است که کاربر نهایی نیازی به نصب هیچ نسخهای از Node را نداشته باشد. این ابزار تایپاسکریپت را از یک تجربه زبان مدیریتشده (managed-language) به یک ابزار برنامهنویسی سیستمی تبدیل میکند. شما اکنون میتوانید با اجرای دستور scriptc coverage بررسی کنید که دقیقاً کدام دستورات پروژه شما بهصورت بومی کامپایل میشوند و کدامها در حالت پویا باقی میمانند.
گام بعدی شما
- اگر ابزارهای CLI با تایپاسکریپت مینویسید، پروژه را با
scriptc coverageتحلیل کنید تا میزان سازگاری استاتیک آن را بسنجید. - برای کاهش هزینههای زیرساختی در Edge Functions، جایگزینی Node.js با باینریهای scriptc را تست کنید.
- مستندات LLVM را مطالعه کنید تا متوجه شوید چگونه این کامپایلر کد شما را به زبان ماشین تبدیل میکند.
اما تأثیر این رویکرد بر اکوسیستم مدلهای زبانی که کد تولید میکنند حتی پیچیدهتر است — به تحلیل ما دربارهی Vibe Coding مراجعه کنید.




گفتگو