برنامه نویسی

خداحافظ و با تشکر از “typescript-is” (جد “typia”، اعتبارسنجی 20000 برابر سریعتر)

خلاصه

این داستان در مورد یک کتابخانه پیشرو است typescript-is:

  • یک کتابخانه اجدادی وجود داشته است typia تحت عنوان typescript-is
    • فقط یک خط مورد نیاز است
    • کامپایل AoT (پیش از زمان) از طریق TypeScript Compiler API
    • بسیار راحت از هر کتابخانه اعتبارسنجی دیگری مانند zod و class-validator
  • من یک کتابخانه دیگر داشتم typescript-json
    • سرعت سریال سازی JSON را افزایش دهید
    • تولید طرحواره JSON
    • مانند کامپایل AOT را انجام می دهد typescript-is
  • من توسعه یافته بودم nestia با ترکیب هر دوی آنها
    • NestJS کتابخانه کمکی
    • اعتبار سنجی توسط typescript-is
    • تقویت کننده JSON و نسل Swagger توسط typescript-json
  • typescript-is تعمیر و نگهداری از دو سال پیش متوقف شده است
  • تغییر کرده ام typescript-json پوشاندن typescript-is امکانات
    • اضافه شدن ویژگی های اعتباردهنده مانند typescript-is
    • با کدهای تست 1M LOC بهبود یافته است
    • تغییر نام به typia
  • امروز درخواست دادم typescript-is نویسنده برای حمایت typia
    • نویسنده از typescript-is موافقت کرد
    • از این به بعد، typescript-is متحد شده است با typia، به طور رسمی
  • با تشکر برای چالش پیشگام از typescript-is، و خداحافظی کنید

مخازن مرتبط:

typescript-is

امکانات

export function is<T>(input: unknown): input is T;
export function assertType<T>(input: unknown): T;
export function validate<T>(input: unknown): ValidationResult<T>;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

فایل منبع TypeScript

import { is } from "typescript-is";

is<number>(3);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

فایل جاوا اسکریپت کامپایل شده

import { is } from "typescript-is";

((input) => {
    if (typeof input !== "number")
        return false;
    return true;
})(3);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این مجموعه AoT است. typescript-is کدهای منبع TypeScript را تجزیه و تحلیل می کند و به کدهای جاوا اسکریپت بهینه برای نوع هدف تبدیل می کند T (number).

https://github.com/woutervh-/typescript-is

مدتها پیش، یک کتابخانه معتبر معتبر به نام وجود داشت typescript-is.

کامپایل AoT (پیش از زمان) را از طریق TypeScript Compiler API انجام داده بود. از آنجایی که فقط به یک خط با نوع TypeScript خالص مانند بالا نیاز دارد، بسیار راحت از هر کتابخانه اعتبارسنجی دیگری مانند zod یا class-validator.

در مورد من، من سرور باطن را از طریق توسعه داده بودم NestJS چارچوب به هر حال، NestJS توسعه دهنده توصیه به استفاده از class-validatorیکی از وحشتناک ترین کتابخانه ها نسبت به آنچه که تا به حال تجربه کرده ام. این کاربر را مجبور می کند تا ساختار تکراری چهارگانه را تعریف کند و سرعت اعتبار سنجی بسیار آهسته بسیار آهسته است (6 مگابایت بر ثانیه). حتی اشکالات بسیار زیادی دارد که برای داده های اشتباه می گویند “مشکلی وجود ندارد” و به نظر می رسد که نگهدارنده علاقه ای به رفع این اشکالات ندارد.

// CLASS-VALIDATOR REQUIES DUPLCIATED DEFINITIONS
export class BbsArticle {
    @ApiProperty({
        type: () => AttachmentFile,
        nullable: true,
        isArray: true,
        description: "List of attached files.",
    })
    @Type(() => AttachmentFile)
    @IsArray()
    @IsOptional()
    @IsObject({ each: true })
    @ValidateNested({ each: true })
    files!: AttachmentFile[] | null;
}

// TYPESCRIPT-IS OKAY WITH PURE TYPESCRIPT TYPE
export interface IBbsArticle {
    /**
     * List of attached files.
     */
    files: IAttachmentFile[] | null;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • class-validator فقط 16 مورد را آزمایش می کند
  • typescript-is حدود 100 مورد را آزمایش می کند
  • typia 10K مورد را با 1M کد LOC آزمایش می کند

در عوض، من دوست داشتم استفاده کنم typescript-is که در NestJS پروژه ها. بسیار راحت و امن تر از آن بود class-validator. فقط یک خط مورد نیاز بود و نیازی به باگ های بسیار زیاد نیست (typescript-is همچنین نمی‌توانست انواع اتحاد یا پیچیده را تأیید کند، اما نه به اندازه جدی class-validator).

استفاده كردن typescript-is برای NestJS پروژه های باطنی، من ایده نابغه آنها را تحسین می کردم typescript-is نویسنده، و همیشه سپاسگزارم که مرا از کابوس رها کرد class-validator.

اگر احساس می کنید این داستان را در جایی شنیده اید، حق با شماست. typescript-is یک کتابخانه اجدادی است typia، و پروژه ای است که قبلاً یک اعتبار سنجی مبتنی بر کامپایل AOT پیاده سازی کرده است typia.

با این حال، تعمیر و نگهداری از 2 سال پیش متوقف و شکسته شده بود.

typescript-json

// JSON SCHEMA GENERATOR
export function application<
    Types extends unknown[], 
    Purpose extends "swagger"|"ajv"
>(): IJsonSchema;

// JSON SERIALIZATION BOOSTER
export function stringify<T>(input: T): string;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تقریباً در همان زمان، کتابخانه دیگری به نام ساخته بودم typescript-json.

آن را مانند AoT (پیش از زمان) انجام می دهد typescript-is، اما برای اعتبار سنجی زمان اجرا نبود، بلکه برای تولید طرحواره JSON بود. درباره تقویت سریال سازی JSON، typescript-json استفاده کرده بود fast-json-stringify توسط طرح JSON به طور خودکار تولید می شود.

برای مرجع، هدف از typescript-json زیر انجام شد nestia، تولید اسناد Swagger با نوع TypeScript خالص.

nestia

لوگوی نستیا

https://github.com/samchon/typia

استفاده كردن typescript-is که در NestJS توسعه‌های باطن بسیار آسان‌تر و راحت‌تر بودند.

با این حال، در آن صورت، امکان تولید اسناد Swagger وجود نداشت. این به این دلیل است که ژنراتور فحشا NestJS نتوانست کد منبع TypeScript را در سطح کامپایل تجزیه و تحلیل کند. در عوض، از طریق فراخوانی تابع دکوراتور به تعاریف تکراری چهارگانه نیاز داشت.

در آن زمان، فکر می‌کردم بهتر است یک ژنراتور swagger جایگزین برای آن بسازم NestJS پروژه اگرچه به منطق های پیچیده ای مانند تحلیل نیاز دارد NestJS با استفاده از کدهای منبع تایپ اسکریپت در سطح کامپایل، فکر کردم به جای بازگشت به حالت وحشتناک، کار بسیار ارزشمندی است. class-validator. من می خواستم پیشرفت کنم تا پسرفت.

بنابراین، من یک کتابخانه جدید به نام ساخته بودم nestia. اعتبارسنجی را از طریق انجام داده بود typescript-isو اسناد Swagger را از طریق تولید کرده بود typescript-json. همچنین پس از موفق به تجزیه و تحلیل NestJS کدهای منبع، ویژگی‌های بیشتری مانند SDK (کیت توسعه نرم‌افزار) تولیدکننده کتابخانه مانند زیر ساختم.

اعضای تیم من (به ویژه توسعه دهندگان فرانت اند) از آن بسیار راضی بودند، و با نگاه کردن به آنها، فکر می کردم که “تصمیم درستی انجام دادم”. در نتیجه اجتناب از class-validator، که من واقعاً نمی خواهم از آن استفاده کنم و زیبا را دنبال می کنم typescript-is، حتی از جمله توسعه دهندگان فرانت اند، کارایی بیش از دو برابر شده است.

SDK

سمت چپ است NestJS کد سرور، و سمت راست کد کلاینت (frontend) با استفاده از SDK است.

در عصر حاضر، nestia می تواند شبیه ساز ساختگی ایجاد کند، و حتی امکان ساخت آن کتابخانه SDK و شبیه ساز Mockup از طریق یک swagger.json فایل. این بدان معناست که شما می توانید کتابخانه SDK و شبیه ساز Mockup را از هر زبان و فریمورک بسازید.

  • SDK: مجموعه ای از fetch توابع با تعاریف نوع
  • شبیه ساز Mockup: شبیه ساز باطن جاسازی شده در SDK

مرگ typescript-is

typescript-is نویسنده تعمیر و نگهداری را متوقف کرده است و این یک مشکل حیاتی برای آن بود nestia.

لحظه ای که برای انتخاب درست تشویق شدم و با هم تیمی هایم سرگرم شدم، typescript-is به طور ناگهانی درگذشته است در واقع، typescript-is حتی قبل از شروع کار از تعمیر خارج شده بود nestia توسعه. متاسفانه در آن لحظه، TypeScript چندین بار در API کامپایلر تغییر زیادی کرده بود و typescript-is از 2 سال پیش شکسته بود

خیلی شرم آور بود که typescript-is مدتی پس از ساخت ناگهان مرد nestia و چشیدن میوه های آن در آن زمان، مدتی فکر کردم که آیا باید به وضعیت وحشتناک و ناامید برگردم class-validator یا نه. در حال توسعه nestia، من حدود یک سال مصرف کرده بودم و یک سال زمان کمی نیست. بنابراین مدتی به آن فکر کردم.

با این حال، تصمیم نهایی من همچنان همان تصمیم قبلی بود: “بیایید یک چیز بیشتر و یک سال بیشتر بسازیم. به جای استفاده از آن وحشتناک class-validator باز هم منطقی است که یک سال دیگر را سپری کنم و این یک فرصت عالی برای مطالعه برای من خواهد بود.”

typia

// RUNTIME VALIDATORS
export function is<T>(input: unknown): input is T; // returns boolean
export function assert<T>(input: unknown): T; // throws TypeGuardError
export function validate<T>(input: unknown): IValidation<T>; // detailed
export const customValidators: CustomValidatorMap; // for customization

// JSON FUNCTIONS
export namespace json {
    export function application<T>(): IJsonApplication; // JSON schema
    export function assertParse<T>(input: string): T; // type safe parser
    export function assertStringify<T>(input: T): string; // safe and faster
}

// PROTOCOL BUFFER (NOT YET, BUT SOON)
export namespace protobuf {
    export function message<T>(): string; // Protocol Buffer message
    export function assertDecode<T>(buffer: Buffer): T; // safe decoder
    export function assertEncode<T>(input: T): Uint8Array; // safe encoder
}

// RANDOM GENERATOR
export function random<T>(g?: Partial<IRandomGenerator>): T;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

https://github.com/samchon/typia

تکامل یافته است typescript-json پوشاندن typescript-is ویژگی ها، و تغییر نام به typia.

مانند typescript-is تعمیر و نگهداری متوقف شده بود و با به روز رسانی کامپایلر TypeScript شکسته شده بود، و این یک مشکل حیاتی برای پروژه من بود nestia، تصمیم گرفتم تقویت کنم typescript-json پوشاندن typescript-is امکانات. همچنین، من تغییر نام داده بودم typescript-json به typia، زیرا آن کتابخانه دیگر فقط برای توابع مرتبط با JSON طراحی نشده است.

همچنین، به عنوان typescript-json برای تولید طرحواره JSON از انواع TypeScript طراحی شده بود، باید تعریف ابرداده به خوبی برای انواع TypeScript طراحی شده باشد. بعلاوه، typescript-is ساختار ابرداده را طراحی نکرده بود و فقط کدهای سخت زیادی نوشت if عبارات برای انواع TypeScript. چنین متفاوت ساخته شده است typia برای داشتن LOC (خط کدها) بسیار بیشتر از typescript-is، ولی typia می تواند بسیار پایدار از قبل باشد typescript-is.

علاوه بر این، من بهبود یافته است typia از طریق 1000000 کد تست LOC. با در نظر گرفتن ویژگی های typia با استفاده از نوع TypeScript خالص، typia باید از هر مورد TypeScript پشتیبانی کند. همچنین، قدرت بیان TypeScript در مورد نوع بسیار قوی تر و گسترده تر از هر زبان دیگری است. بنابراین، برای پشتیبانی ایمن از هر نوع TypeScript، مجبور شدم کدهای آزمایشی عظیمی در حدود یک میلیون LOC بنویسم. در طول یک سال برای من کار سختی بود، اما چنین استقامتی تکامل یافت typia تنها یک کتابخانه اعتبار سنجی است که از هر نوع TypeScript پشتیبانی می کند.

  • typia 10K مورد را با 1M کد LOC آزمایش می کند
  • typescript-is حدود 100 مورد را آزمایش می کند
  • class-validator فقط 16 مورد را آزمایش می کند

ساختار داده از typia برای انواع TypeScript:

برای مرجع، به عنوان typescript-is چنین تعریف متادیتای ساختار یافته ای ندارد و دلیل آن هم همین است typescript-is نمی تواند نوع پیچیده را تأیید کند. با این حال، بهانه ای برای typescript-is، در آن زمان پایدارترین کتابخانه اعتبارسنجی بود و حتی بسیار پایدارتر از مخوف تر class-validator

  • ts-is به معنای typescript-is
  • c.v. به معنای class-validator

همچنین، به عنوان typia مهارت کامپایل AoT (پیش از زمان) را انجام می دهد و nestia از چنین مواردی استفاده می کند typia ویژگی ها، من می توانم افزایش دهم NestJS عملکرد فوق العاده جاری nestia می تواند افزایش دهد NestJS عملکرد سرور مانند زیر:

  raw `assert()` معیار تابع endraw

  • سرعت اعتبارسنجی 20000 برابر بیشتر از class-validator
  • سرعت سریال سازی JSON 200 برابر بیشتر از class-transformer
  • کامپوزیت NestJS عملکرد سرور 30 ​​برابر است
  • نتایج محک

خداحافظ typescript-is

https://github.com/woutervh-/typescript-is/issues/137

یک سال از توسعه موفقیت آمیز می گذرد typia. و در این بین، typescript-is هنوز از تعمیر خارج شده است بنابراین، من یک موضوع را نوشته ام typescript-is repo درخواست لغو اعتبار typescript-is و حفظ کنید typia بجای.

ضمن نگارش موضوع، پیام قدردانی هم گذاشتم typescript-isایده های پیشگام و فداکاری های گذشته که به من کمک کرد تا از شرایط وحشتناک فرار کنم class-validator. با تشکر از ایده عالی او، و من با انگیزه از پروژه او می توانم چیزهای زیادی یاد بگیرم.

در هفته گذشته، typescript-is نویسنده پیشنهاد من را پذیرفت و typescript-is حفظ را آغاز کرده است typia. از این به بعد، typescript-is متحد شده است با typia، به طور رسمی با تشکر برای چالش پیشگام از typescript-is، و خداحافظی کنید.

داستان بعدی

تبیین نظری

اخیراً مقالاتی در مورد کامپایل AoT نوشته ام.

به هر حال، من فقط به شما گفتم که کامپایل AoT بسیار سریعتر از منطق های دسترسی به کلید پویا است، اما از نقطه نظر تئوری توضیح داده نشده است. مقاله بعدی در مورد آن خواهد بود.

بیایید دلیل اینکه چرا کامپایل AoT کد شما را سریعتر می کند را مطالعه کنیم.

پشت سر داستان نستیا

من دوست ندارم class-validator به دلیل تجربه بد

هنگام توسعه a NestJS سرور باطن در مورد خدمات بیمه، من استفاده کردم class-validator، اما از عملکرد بسیار کند آن رنج می برد. class-validator می تواند تنها 6 مگابایت داده در هر ثانیه اعتبار سنجی کند و متاسفانه هر قرارداد بیمه به راحتی از 3 مگابایت فراتر می رود. در آن زمان، سرور باطن من می تواند تنها 4 اتصال در ثانیه داشته باشد و این یک مشکل حیاتی برای تجارت بود.

این دلیلی بود که من آن را رها کردم class-validator و استفاده کرد typescript-is بجای. و همانطور که از این مقاله می توانید ببینید، چنین تجربه بدی باعث پیشرفت من شد typia و nestia. مقاله بعدی در مورد این داستان خواهد بود.

اگر می‌توانید زبان کره‌ای بخوانید، می‌توانید داستان را همین الان از اینجا بخوانید. اگر نه، لطفاً منتظر مقاله بعدی من باشید.

https://docs.google.com/presentation/d/1zOsUwSVinhi2FIyPH8yj0AMDlZgJbBRn/edit?usp=sharing&ouid=103963163922171200617&rtpof=true&sd=true

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا