تجزیه و تحلیل استاتیک

تجزیه و تحلیل استاتیک نوعی آزمایش است که بررسی خودکار کد شما را بدون اجرای واقعی آن یا نیاز به نوشتن یک تست خودکار فراهم می کند. اگر از یک IDE مانند VSCode استفاده می‌کنید احتمالاً قبلاً این نوع آزمایش را دیده‌اید - بررسی نوع انجام شده توسط TypeScript نوعی تجزیه و تحلیل استاتیک است و می‌تواند به‌عنوان خطوط پیچ‌خورده در زیر خطاها یا هشدارها نشان داده شود.

ESLint ابزاری است که می تواند در مورد مشکلات احتمالی در پایگاه کد شما بازخورد ارائه دهد. این مشکلات ممکن است از نوع ایمن باشند، اما خطاها یا رفتارهای غیراستاندارد در نوع خود هستند. ESLint به شما امکان می دهد تعدادی از قوانین را که در پایگاه کد شما بررسی می شوند، اعمال کنید، از جمله بسیاری از قوانین در مجموعه "توصیه شده" آن.

یک مثال خوب از قانون ESLint، قانون نه ناامن نهایی آن است. این شما را از نوشتن عباراتی که جریان کنترل برنامه شما را در یک بلوک finally تغییر می‌دهند، جلوگیری می‌کند. این یک قانون عالی است، زیرا انجام این یک روش غیرعادی برای نوشتن جاوا اسکریپت است که پیروی از آن دشوار است. با این حال، این چیزی است که یک فرآیند بررسی کد سالم باید بتواند آن را تشخیص دهد.

  try {
   
const result = await complexFetchFromNetwork();
   
if (!result.ok) {
     
throw new Error("failed to fetch");
   
}
 
} finally {
   
// warning - this will 'overrule' the previous exception!
   
return false;
 
}

به این ترتیب، ESLint جایگزینی برای یک فرآیند بررسی سالم (و یک راهنمای سبک است که تعریف می‌کند پایگاه کد شما چگونه باید باشد) نیست، زیرا قرار نیست هر رویکرد غیرمتعارفی را که یک توسعه‌دهنده ممکن است سعی کند در پایگاه کد شما معرفی کند، به تصویر بکشد. راهنمای تمرین‌های مهندسی Google بخش کوتاهی در مورد «ساده نگه داشتن آن» دارد.

ESLint به شما امکان می دهد یک قانون را بشکنید و کد را به عنوان "مجاز" حاشیه نویسی کنید. به عنوان مثال، می توانید منطق قبلی را با حاشیه نویسی به صورت زیر مجاز کنید:

  finally {
   
// eslint-disable-next-line no-unsafe-finally
   
return false;
 
}

اگر متوجه شدید که دائماً یک قانون را زیر پا می گذارید، آن را خاموش کنید. این ابزارها شما را تشویق می‌کنند تا به روشی خاص کد بنویسید، اما ممکن است تیم شما به روشی متفاوت کد بنویسد و از خطرات آن رویکرد آگاه باشد.

در نهایت، فعال کردن ابزارهای تجزیه و تحلیل ایستا در یک پایگاه کد بزرگ ممکن است نویزهای غیرمفید زیادی (و مشغله کاری برای بازسازی) روی کد ایجاد کند که در غیر این صورت خوب کار می کرد. بنابراین فعال کردن آن در اوایل چرخه عمر پروژه آسان تر است.

پلاگین های ESLint برای پشتیبانی از مرورگر

می‌توانید افزونه‌ای را به ESLint اضافه کنید که استفاده از APIهایی را که به طور گسترده پشتیبانی نمی‌شوند یا توسط فهرست مرورگر مورد نظر شما پشتیبانی نمی‌شوند، علامت‌گذاری می‌کند. بسته eslint-plugin-compat می‌تواند به شما هشدار دهد که ممکن است یک API در دسترس کاربران شما نباشد، بنابراین لازم نیست دائماً خودتان را پیگیری کنید.

بررسی نوع برای تجزیه و تحلیل استاتیک

هنگام یادگیری جاوا اسکریپت، توسعه دهندگان جدید معمولاً با این ایده آشنا می شوند که این یک زبان با تایپ ضعیف است. یعنی می‌توان یک متغیر را به عنوان یک نوع اعلام کرد، سپس از همان مکان برای چیزی کاملاً متفاوت استفاده کرد. این شبیه پایتون و سایر زبان های اسکریپت است، اما بر خلاف زبان های کامپایل شده مانند C/C++ و Rust.

این نوع زبان ممکن است برای شروع خوب باشد - و مسلماً همین سادگی است که جاوا اسکریپت را بسیار محبوب کرده است - اما اغلب برای برخی از پایگاه‌های کد نقطه شکست است، یا حداقل چیزی است که اجازه می‌دهد خطاهای گیج کننده رخ دهد. به عنوان مثال، با ارسال number که در آن string یا یک نوع شی مورد انتظار بود، آن مقدار تایپ شده نادرست می‌تواند در کتابخانه‌های مختلف منتشر شود و در نهایت باعث ایجاد یک TypeError گیج‌کننده شود.

TypeScript

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

برای مثال سریع، این کد، که انتظار دارد با پذیرش نام string و سن number ، یک تماس پاسخ داده شود:

const callback = (name: string, age: string): void => {
  console
.info(name, 'is now', age, 'years old!');
};
onBirthday
(callback);

هنگام اجرا از طریق TypeScript یا حتی زمانی که نشانگر ماوس را روی یک IDE قرار می دهد، خطای زیر را ایجاد می کند:

bad.ts:4:12 - error TS2345: Argument of type '(name: string, age: string) => void' is not assignable to parameter of type '(name: string, age: number) => void'.
  Types of parameters 'age' and 'age' are incompatible.
    Type 'number' is not assignable to type 'string'.

4 onBirthday(callback);
             ~~~~~~~~

Found 1 error in bad.ts:4
کد مثال قبلی در یک IDE با پیغام خطا در یک پاپ آپ نمایش داده می شود.
VSCode نشان می دهد که شما یک نوع نادرست را پاس کرده اید.

در نهایت، هدف از استفاده از TypeScript جلوگیری از ورود خطاهایی مانند این - سن باید یک number باشد، نه یک string - است. تشخیص این نوع خطا با استفاده از انواع دیگر آزمون دشوار است. علاوه بر این، سیستم نوع می‌تواند قبل از نوشتن یک آزمون بازخورد بدهد. این می‌تواند فرآیند نوشتن کد را با دادن بازخورد اولیه درباره خطاهای نوع در حین توسعه نرم‌افزار، به جای زمانی که کد در نهایت اجرا می‌شود، آسان‌تر کند.

چالش برانگیزترین بخش استفاده از TypeScript تنظیم صحیح آن است. هر پروژه به یک فایل tsconfig.json نیاز دارد، که در حالی که در درجه اول توسط خود ابزار خط فرمان tsc استفاده می شود، توسط IDE هایی مانند VSCode همراه با بسیاری از ابزارهای ساخت و ابزارهای دیگر، از جمله Vitest نیز خوانده می شود. این فایل حاوی صدها گزینه و پرچم است و می‌توانید منابع خوبی برای تنظیم آن در اینجا پیدا کنید:

نکات عمومی TypeScript

هنگام تنظیم و استفاده از TypeScript از طریق یک فایل tsconfig.json ، موارد زیر را در نظر داشته باشید:

  • مطمئن شوید که فایل های منبع شما واقعاً گنجانده شده و بررسی شده اند. اگر فایلی به طور مرموزی "هیچ خطایی ندارد"، احتمالاً به این دلیل است که بررسی نمی شود.
  • تشریح صریح انواع و رابط‌ها در فایل‌های .d.ts ، به‌جای توصیف ضمنی آن‌ها هنگام نوشتن توابع، می‌تواند پایگاه کد شما را آسان‌تر آزمایش کند. هنگامی که رابط های درگیر واضح هستند، نوشتن نسخه های مسخره و «جعلی» کد آسان تر است. .

TypeScript ضمنی هر

یکی از قدرتمندترین و ارزشمندترین گزینه های پیکربندی TypeScript، پرچم noImplicitAny است. با این حال، فعال کردن آن نیز اغلب دشوار است، به خصوص اگر از قبل یک پایگاه کد بزرگ دارید. (اگر در حالت strict هستید، پرچم noImplicitAny به طور پیش فرض فعال است، اما نه در غیر این صورت.)

این پرچم باعث می شود که این تابع یک خطا برگرداند:

export function fibonacci(n) {
 
if (n <= 1) {
   
return 0;
 
} else if (n === 2) {
   
return 1;
 
}
 
return fibonacci(n - 1) + fibonacci(n - 2);
}

اگرچه، به عنوان یک خواننده، کاملاً واضح است که n باید یک عدد باشد، TypeScript نمی تواند با اطمینان این را تأیید کند. اگر از VSCode استفاده می کنید، با نگه داشتن ماوس روی تابع، آن را به صورت زیر توصیف می کنید:

function fibonacci(n: any): any

فراخوان‌کنندگان این تابع می‌توانند از یک مقدار از نوع any (نوعی که هر نوع دیگری را اجازه می‌دهد) عبور کنند، نه فقط یک number . با فعال کردن پرچم noImplicitAny ، می‌توانید از این نوع کدها در طول توسعه محافظت کنید، بدون اینکه نیازی به نوشتن تست‌های منطق تجاری گسترده برای کد خود داشته باشید که انواع داده‌های اشتباه را در مکان‌های خاص ارسال می‌کند.

راه حل ساده در اینجا این است که هم آرگومان n و هم نوع برگشتی fibonacci را به عنوان number علامت گذاری کنیم.

پرچم noImplicitAny مانع از نوشتن صریح any در پایگاه کدتان نمی شود. همچنان می توانید تابعی بنویسید که any نوع را بپذیرد یا برگرداند. این فقط تضمین می کند که به هر متغیر یک نوع بدهید.