پلاگین Babel که اسکیماهای Zod رو سریعتر میکنه
خلاصهٔ کاملتر
این پروژه یه پلاگین برای Babel هست که کارش یه چیز مشخصه: تعریف اسکیماهای Zod رو میبره بالای فایل، یعنی hoist میکنه. به گفتهٔ سازنده، انگیزهٔ اصلی اینه که initialize کردن اسکیمای Zod گرونه و اگه اسکیما رو داخل یه تابع تعریف کنی، هر بار که اون تابع صدا زده میشه، اسکیما از نو ساخته میشه.
حالت معمول اینطوریه که اسکیما داخل تابع تعریف میشه و هر بار دوباره ساخته میشه:
function getSchema() {
return z.object({ name: z.string() });
}پلاگین این رو طوری بازنویسی میکنه که اسکیما یکبار توی یه const بالای فایل ساخته بشه و تابع فقط همون مقدار آمادهٔ ساختهشده رو برگردونه. در نتیجه هزینهٔ ساختن دوباره بهکل حذف میشه.
سازنده یه جدول بنچمارک هم گذاشته (با Zod نسخهٔ 4.3.5 و Node 22) که اختلاف رو خیلی چشمگیر نشون میده: از یه آبجکت ساده که حدود ۴۰۰ برابر سریعتر میشه تا discriminated union که تا ۶۲۷ برابر جهش داره. بهطور کلی بسته به شکل اسکیما، hoisting بین ۱۱۳ تا ۶۲۷ برابر سریعتره. مزیت دیگهش اینه که هیچ زحمت ذهنی یا تغییری توی کد لازم نداره؛ کد عادی Zod مینویسی و این کار خودکار انجام میشه.
یه بخش جالبتر هم داره: پلاگین اسکیماهایی که از یه base ایمپورتشده با ترکیبکنندههای Zod ساخته میشن رو هم hoist میکنه؛ مثل .extend()، .pick()، .omit()، .merge() و .partial(). این تعریفهای hoistشده حتی بالای دستورهای import گذاشته میشن و سازنده میگه این کار امنه، چون توی ES module ایمپورتها قبل از هر کد دیگهای مقداردهی میشن.
اما یه چالش ظریف اینجا هست: Babel هیچ اطلاعاتی از نوعها (type) نداره، پس باید یه نشونه داشته باشه که base واقعاً یه اسکیمای Zod هست، وگرنه ممکنه APIهای بیربطی مثل dayjs.extend(plugin) رو هم اشتباهی بازنویسی کنه. برای همین یه زنجیره فقط وقتی hoist میشه که یا جایی توش یه صدا زدن z.* باشه، یا اسمِ شناسهٔ base با الگوی schemaNamePattern بخونه که پیشفرضش /ZodSchema$/ هست. این الگو رو میتونی بهصورت RegExp، رشته (برای کانفیگهای JSON) یا null (برای غیرفعال کردن تطبیق اسمی) بدی.
یه نکتهٔ ایمنی دیگه هم رعایت شده: اسکیماهایی که به متغیر محلی، this، یا bindingهای const/let/var سطح بالا ارجاع میدن هرگز hoist نمیشن، چون این کار میتونه رفتار رو عوض کنه یا خطای temporal dead zone بسازه. فقط اسکیماهایی که کاملاً از ایمپورتها و مقادیر ثابت ساخته شدن hoist میشن.
نکات کلیدی:
- پلاگین babel-plugin-zod-hoist تعریف اسکیماهای Zod رو میبره بالای فایل تا فقط یکبار initialize بشن
- طبق بنچمارک سازنده بین ۱۱۳ تا ۶۲۷ برابر سریعتر، بدون هیچ تغییری توی کد
- اسکیماهای مشتقشده با ترکیبکنندههایی مثل .extend() و .pick() رو هم hoist میکنه
- چون Babel نوعها رو نمیبینه، با وجود یه صدا زدن z.* یا تطبیق با الگوی schemaNamePattern تشخیص میده
- اسکیماهای وابسته به متغیر محلی یا this برای جلوگیری از تغییر رفتار، hoist نمیشن




