استانداردسازی تایپ اسکریپت با ESLint و Prettier – به زبان ساده


در آغاز استفاده از تایپ اسکریپت در یک پروژه جدید یا قدیمی، میبایست استانداردهایی برای مسیر کدنویسی تعیین کنید. به همین جهت است که امکان linting و formatting را از طریق ESLint و Prettier به پروژههای خود اضافه میکنیم. در این مقاله با روش استانداردسازی تایپ اسکریپت با ESLint و Prettier آشنا خواهیم شد.
Linting در تایپ اسکریپت چه مفهومی دارد؟
با این که کامپایلر تایپ اسکریپت از طریق بررسی نوع استاتیک ما را ملزم به اصلاح کد میکند، اما چند کار مهم وجود د آرد که انجام نمیدهد. به طور خاص، تایپ اسکریپت امکان کامپایل شدن یا نشدن کد را بررسی میکند، اما قابلیت Linting گستردهتر از آن است و بررسی میکند آیا کد از بهترین رویههای مناسب اکوسیستم جاوا اسکریپت پیروی میکند یا نه.
اگر بخواهیم این دو مورد را مقایسه کنیم، تفاوتشان مانند تفاوت یک غلطیاب املایی (spell checker) و غلطیاب گرامری (grammar checker) است. در ادامه جملهای را میبینید که آزمون یک غلطیاب املایی را پاس میکند:
Frog cloud red molecule ambivalent forty two.
اما در صورتی که غلطیاب گرامری جمله فوق را بخواند، احتمالاً به عقل نویسندهاش شک خواهد کرد!
دقیقاً به همین ترتیب، کامپایلر تایپ اسکریپت صرفاً بررسی میکند آیا کد از نظر ساختاری معنا دارد یا نه. اما Linter کد را در خصوص مواردی مانند فهرست زیر بررسی میکند:
- از کلیدواژه any استفاده نشده باشد.
- اینترفیسهای marker (خالی) اعلان نشده باشد.
- از روش «نامگذاری شتری» ( camelCase) استفاده شده باشد.
- از قالب رشتهای منسجمی استفاده شده باشد.
- از ts-ignore استفاده نشده باشد.
اساساً یک Linter با به چالش کشیدن برخی مواردی که در طی زمان به کد اضافه شدهاند موجب ارتقای کیفیت کد میشود. این وضعیت به طور خاص در مواردی که توسعهدهندگان جدید به یک تیم یا پروژه اضافه میشوند، مفید است.
Linter-ها بر اساس ماهیت خود، تنظیمات بسیاری دارند، اما این گزینههای متنوع را میتوان تغییر داد. با بهرهگیری از فایلهای پیکربندی که در ادامه بیشتر بررسی خواهیم کرد، و گنجاندن برخی مجموعه قواعد، میتوانید کنترل بیشتری روی طرز کار دقیق Linter خود داشته باشید.
معرفی ESLint
ESLint یک Linter بسیار محبوب برای جاوا اسکریپت و تایپ اسکریپت است که میتواند کد این زبانها را تحلیل کند و هشدارها و خطاهایی بر اساس شدت نقض قواعد مختلف ارائه دهد.
اساساً ESLint در صورتی در مورد یک کد خطا میدهد که با نقض قاعده در سطح error مواجه شود. از این امکان میتوان به عنوان بخشی از pipeline بیلد استفاده کرد تا کامیتهای جدید که شامل موارد نقض قاعده خاصی هستند مورد پذیرش قرار نگیرند.
در گذشته، TSLint برای پروژههای تایپ اسکریپت توصیه میشد، اما Palantir از ابتدای سال 2019، اعلام کرده است که TSLint را به نفع TSLint کنار گذاشته است. به همین جهت بهتر است در پروژههای موجود از TSLint مهاجرت بکنید و در پروژههای جدید هم ز همان آغاز از ESLint بهره بگیرید.
در ادامه ESLint را در یک اپلیکیشن موجود تایپ اسکریپت نصب میکنیم که در حال حاضر از هیچ روش Linting استفاده نمیکند، تا با فرایند کار آشنا شویم.
آغاز کار با NPM
در این بخش از یک اپلیکیشن ساده تایپ اسکریپت استفاده میکنیم که عاری از پیچیدگیهای اپلیکیشنهای تکصفحهای است. در این پروژه از انگولار، ریاکت، ویو و یا حتی جیکوئری استفاده نشده است و صرفاً روی تایپ اسکریپت و کد جاوا اسکریپت که تولید میکند تمرکز کردهایم. این کد در این ریپوی گیتهاب (+) عرضه شده است و در صورتی که قصد پیگیری آن را دارید از تگ migrateEnd (+) آغاز میشود.
با توجه به مقاصد آموزشی این مقاله، میخواهیم از ابزار مدیریت بسته Node به اختصار NPM برای مدیریت وابستگیها و مراحل بیلد استفاده کنیم. در این مقاله فرض کردهایم که شما قبلاً آن را روی سیستم خود نصب کردهاید. اگر چنین نیست به این نشانی (+) بروید و جدیدترین نسخه LTS مربوط به NPM را نصب کنید.
از آنجا که NPM در ریپازیتوری نمونه ما پیکربندی نشده است، باید از دستور npm init در خط فرمان برای ایجاد یک فایل جدید package.json استفاده کنیم. این دستور یک سری پرسشها ارائه میکند که در مورد همه آنها گزینههای پیشفرض درون پرانتز ارائه شدهاند و با زدن اینتر پذیرفته میشوند. صرف نظر از گزینههایی که انتخاب میشوند، یک فایل package.json ایجاد خواهد شد. فایل ما به صورت زیر است:
در خاطر داشته باشید که بخش بزرگی از این فایل، تنها در صورتی اهمیت دارد که بخواهید پکیج خود را به صورت آنلاین منتشر کنید که در مورد این راهنما موضوعیت ندارد.
به بخش scripts سند توجه کنید. هر مدخل در این لیست میتواند از طریق دستور زیر اجرا شود:
npm run [scriptname]
NPM در عمل همه ابزارهای لازم برای کامپوز کردن پردازشهای بیلد کاملاً پیچیده چندمرحلهای را دارد. در ادامه تعاریف اسکریپتهای خود را به این بخش اضافه میکنیم تا از transpile کردن پروژههای تایپ اسکریپت به جاوا اسکریپت پشتیبانی کنیم:
در این بخش یک گام جدید transpile داریم که میتواند از طریق npm run transpile اجرا شود. این دستور به نوبه خود tsc را اجرا میکند که کد تایپ اسکریپت را به کد جاوا اسکریپت تبدیل میکند. باید اذعان کرد که فرایند طولانیتری برای به دست آوردن تأثیر مشابه محسوب میشود، اما این مزیت را دارد که میتوانیم شروع به ساخت بیلدهای چندبخشی بکنیم.
همچنین یک گام build تعریف کردهایم که از آن برای اجرای چندین مرحله در یک دستور منفرد استفاده خواهیم کرد. در این مورد گام build صرفاً مرحله transpile را اجرا میکند، اما در بخش بعدی با افزودن ESLint شیوه بسط یافتن آن را خواهیم دید.
نصب ESLint
در این بخش، اقدام به نصب ESLint و تنظیم فرایند Linting میکنیم. از npm برای نصب وابستگیهای توسعه روی ESLint به وسیله دستور زیر کمک میگیریم:
npm i -D typescript eslint eslint-config-typescript
در دستور فوق i اشاره به کلمه «نصب» (install) و –D اشاره به دستورالعمل NPM برای ذخیره وابستگی در فایل package.json به صورت یک وابستگی صرفاً در مرحله «توسعه» (development) دارد.
بدین ترتیب وابستگیهای مورد نیاز در پوشه node_modules دانلود میشوند و بر اساس نسخههای وابستگی که نصب شدهاند مداخلی در فایل package.json نوشته خواهد شد. در زمان نگارش این راهنما این موارد به صورت زیر بودهاند:
این دستور در عمل به همه دستورهای npm i بعدی اطلاع میدهد که به دنبال این نسخه از وابستگیها یا نسخههای جدیدتر آنها بگردند (که با کاراکتر ^ مشخص شده است).
پیکربندی ESLint برای تایپ اسکریپت
اکنون که ESLint نصب شده است، باید آن را پیکربندی کنیم. به این منظور دستور زیر را اجرا میکنیم:
eslint –init
به این ترتیبی اعلان دریافت میشود که از شما میخواهد طرز رفتار ESLint را تعیین کنید. با توجه به مقاصد آموزشی این مقاله، ما نمیخواهیم استایل کدنویسی خاصی را الزام کنیم و از این رو گزینه check syntax and find problems را انتخاب میکنیم.
در ادامه ESLint میپرسد از چه نوع ساختار ماژول جاوا اسکریپت استفاده میکنید. در این مورد ما همه چیز را ساده حفظ میکنیم و از هیچ ماژول جاوا اسکریپتی استفاده نمیکنیم. از این رو گزینه none of these را انتخاب میکنیم.
پس از آن ESLint میپرسد آیا از یک فریمورک اپلیکیشن تکصفحهای استفاده میکنید یا نه. در این مورد اپلیکیشن ما صرفاً یک اپلیکیشن قدیمی ساده جاوا اسکریپت است که با DOM تعامل دارد و از این رو بار دیگر گزینه none of these را انتخاب میکنیم.
سپس none of these سؤال میکند آیا از تایپ اسکریپت استفاده میکنید که پاسخ مثبت است و گزینه yes را انتخاب میکنیم.
در ادامه ESLint در مورد محیطی که کد اجرا خواهد شد سؤال میکند. در این مورد کد قرار است روی مرورگر اجرا شود و از این رو گزینه پیشفرض مناسب است.
در نهایت، ESLint از شما میپرسد که میخواهید تنظیمات چگونه ذخیره شوند. میتوانید از گزینه ترجیحی خود استفاده کنید، اما ما در این مقاله از قالب JSON استفاده میکنیم که برای کار با فایلهای تایپ اسکریپت و همچنین فایل packages.json معقولتر است.
ESLint ممکن است در مورد نصب وابستگیهای اضافی بر اساس گزینههایی که انتخاب کردهاید نیز سؤالاتی بپرسد که باید جواب مثبت بدهید.
بدین ترتیب تنظیمات ESLint پیکربندی شده و در یک فایل.eslintrc.json مانند زیر ذخیره میشوند:
تحلیل کد تایپ اسکریپت با استفاده از ESLint
اکنون که ESLint را نصب و پیکربندی کردهایم نوبت به استفاده از آن رسیده است. ساختار آن شاید تا حدودی پیچیده باشد و شاید نخواهید هر بار از آن استفاده کنید، اما دستور مورد نظر به صورت زیر است:
eslint --ext.ts [pathtosource]
در دستور فوق به اعلام میکنیم که ESLint باید صرفاً روی فایلهای تایپ اسکریپت اجرا شود و در دایرکتوری و زیردایرکتوریهای خاصی بگردد. از آنجا که فایل اپلیکیشن نمونه ما در دایرکتوری root قرار دارد از دستور زیر برای تعیین دایرکتوری جاری استفاده میکنیم:
eslint --ext.ts
با اجرای دستور فوق روی کد نمونهمان برخی موارد نقض قواعد را مشاهده میکنیم:
ما میخواستیم رفتارهای بالقوه مشکلدار را شناسایی کنیم و از این رو Linting کار خود را به خوبی انجام داده است.
اینک در زمان خود کمی صرفهجویی کرده میکنیم و اسکریپتهای package.json را بهروزرسانی میکنیم:
"lint": "eslint --ext.ts.", "build": "npm run lint && npm run transpile",
در دستور فوق گام جدیدی برای lint کردن تعریف میکنیم و گام build خود را از طریق عملگر&& بسط میدهیمت گام lint را فراخوانی کنیم، منتظر نتیجه بمانیم و سپس گام transpile را تنها زمانی که گام lint بدون خطا طی میشود فراخوانی کنیم.
اکنون میتوانیم دستور زیر را برای lint کردن transpile کردن کد تایپ اسکریپت به مد جاوا اسکریپت اجرا کنیم:
npm run build
اصلاح مشکلات ESLint
گاهی اوقات ESLint برخی موارد خطا را به صورت «مثبت نادرست» (false positives) گزارش میکند. برای نمونه ما برای فراخوانی تابعهایی که در کد جاوا اسکریپت تعریف کردهایم از دستگیرههای کلیک کمک میگیریم و linter ما در مورد کاری که انجام میدهیم سررشتهای ندارد.
زمانی که در مورد رابطه بین تابع جاوا اسکریپت و فایل HTML فکر میکنیم، برای توسعهدهنده جدیدی که به تیم اضافه شده است و روی چیز دیگری کار میکند، ممکن است این رابطه بدیهی نباشد و تابع را حذف کرده یا تغییر نام داده و یا جابجا کند چون معنی دقیق کار خود را درک نمیکند.
برای جلوگیری از بروز چنین مشکلاتی و اصلاح هشدارهای ESLint باید یک نمونه از اصلاح این موارد ارائه کنیم.
در فایل HTML خط مرتبط "()onclick="addTestCase را حذف میکنیم و به جای آن کد بعدی را طوری اصلاح میکنیم تا دکمه را بر اساس ID آن به دست آورد و سپس دستگیره onclick را در کد تعیین کند:
نکته: اگر تورفتگی، گیومه و یا آکولادها در قطعه کد فوق باعث آزردگی شما میشوند، نگران نباشید، چون در ادامه آنها را اصلاح خواهیم کرد.
به این ترتیب یکی از خطاها اصلاح میشود. از همین الگو میتوانیم برای حل مشکلات دیگر نیز استفاده کنیم و یا از این فرصت بهره بگیریم تا شیوه نادیده گرفتن موارد «مثبت نادرست» را نشان دهیم.
فرض کنید با قاعده no-unused-vars موافق نباشیم و البته چنین مخالفتی بیاساس است، زیرا این قاعده خوبی است، اما میخواهیم شدت آن را کمی دستکاری کنیم تا به سطح هشدار کاهش یابد یا کلاً غیر فعال شود.
این کار از طریق مراجعه به فایل eslintrc.json و افزودن شناسه قاعده به کلکسیون rules در فایل به صورت زیر امکانپذیر است:
"rules": { "no-unused-vars": "warn" }
اگر بخواهیم این مورد هیچ هشدار یا خطایی را موجب نشود، میتوانیم آن را به صورت off تنظیم کنیم. البته نباید این کار را انجام دهید. این قاعده خوبی است و باید به صورت یک خطا یا هشدار باقی بماند. هدف ما صرفاً نمایش شیوه غیر فعالسازی قواعد بوده است.
از آنجا که ما با این قاعده موافق هستیم، در عمل ـن را غیر فعال یا غیر خطا نمیکنیم، بنابراین آن را به صورت خط به خط بر اساس کد خودمان غیر فعال خواهیم کرد. بدین ترتیب میتوانیم موارد منفرد «مثبت نادرست» را به شیوه معنادارتری مدیریت کنیم. این کار از طریق ساختار disable-next-line ممکن است:
// eslint-disable-next-line no-unused-vars function deleteTestCase(id: number) { // my logic here }
هر آن چه را که بخواهید مدیریت کنید، به این روش ابزارهایی در اختیار شما قرار میگیرد که میتوانید تعداد خطاها را در ESLint به صفر کاهش دهید و دستور npm run build را پاس کنید.
تعیین استایل کدنویسی با Prettier
اینک که با استفاده از Prettier مشکلهای کد خود را یافته و اصلاح میکنیم، نوبت آن رسیده که مشکلات ظاهری و قالببندی از قبیل تورفتگیهای کد را نیز اصلاح کنیم. این یک مشکل در اپلیکیشنهای پروداکشن است که استانداردهای کدنویسی حائز اهمیت بالایی هستند.
خوشبختانه ابزاری به نام Prettier وجود دارد که نه تنها مورد مختلف مرتبط با قالببندی کد را تشخیص میدهند، بلکه این مشکلات استایلبندی را به صورت خودکار حل نیز میکند. به این ترتیب مجموعه استاندارد قواعد قالببندی موجب جلوگیری از بروز بحثهای طولانی در زمان بررسی کد میشود و اجازه میدهد روی موارد مهمتر یعنی خود کد متمرکز شویم.
بدیهی است که استایلها ممکن است دقیقاً آن چیزی نباشند که شخصاً در مورد آنها تصمیمگیری کنیم، اما در ادامه با روش خواندن استایل کد و حتی تفکر در مورد آن آشنا خواهید شد.
نصب و پیکربندی Prettier
با این که Prettier میتواند بک صورت یک ابزار مستقل عمل کند، اما زمانی که در ESLint ادغام شود، عملکرد بسیار روانتری ارائه میکند. به همین جهت است که Prettier هر بار که Prettier رخ بدهد، اجرا میشود.
کار خود را با نصب کردن وابستگیهای توسعه برای پلاگین Prettier ESLint از طریق دستور زیر آغاز میکنیم:
npm i -D prettier eslint-plugin-prettier eslint-config-prettier
زمانی که این کار پایان یافت، باید فایل eslintrc.json را طوری ویرایش کنیم که در مورد حضور Prettier اطلاع داشته باشد.
در بخش extends دو مدخل زیر را وارد کنید:
"prettier/@typescript-eslint", "plugin:prettier/recommended"
اکنون زمانی که وظیفه lint یا build را از طریق npm اجرا کنیم، هشدارهایی در مورد تورفتگیها، گیومهها یا موارد مشابه به دست میآوریم. اکنون یک استایل الزام میشود و در صورتی که مطابقت نیابد، امکان کامپایل کد وجود نخواهد داشت.
البته این حالت آزاردهنده است و در دنیای واقعی چندان مفید نیست، به جای آن بهتر است کاری کنیم که Prettier به طور خودکار فایل را به طرز صحیح قالببندی کند. امکان این کار وجود دارد. تنها کاری که باید انجام دهیم این است که اسکریپت lint خود را در فایل package.json ویرایش کنیم و فلگ –fix را به آرگومانهای خط فرمان به صورت زیر اضافه کنیم:
"lint": "eslint --fix --ext.ts."
اکنون زمانی که کد را مجدداً اجرا کنیم، فایلهای سورس به صورت خودکار طوری ویریاش میشوند که قالببندی صحیحی پیدا کنند. دلیل این که این کار امکانپذیر است، آن است که برخی قواعد ESLint برخی اصلاحهای خودکار تعریف کردهاند که در صورت تعیین فلگ fix-- میتوانند اعمال شوند.
البته این امکان محدود به قالببندی نیست برخی قواعد جاوا اسکریپت و تایپ اسکریپت اصلاحهای خودکاری ارائه میکنند یعنی در عمل زمانی که یک استایل منسجم را در سراسر کدبیس الزام میکنیم، بررسی کد برای وجود خطاهای مهم میتواند موجب اصلاح برخی مشکلات جزئی نیز شود.
سخن پایانی
در این راهنما دانستیم که استفاده از NPM, ESLint و Prettier موجب تأثیر و بهبود چشمگیری در کار با کدهای تایپ اسکریپت میشود. اگر کنجکاو هستید در مورد قواعد یا پیکربندی ESLint اطلاعات بیشتری کسب کنید، پیشنهاد میکنیم سری به این صفحه (+) بزنید تا در مورد قواعد مختلف، تنظیمات پیشفرض آنها و شیوه سفارشیسازی رفتارشان آگاهتر شوید.
به طور کلی استفاده از تایپ اسکریپت به همراه NPM, ESLint و Prettier موجب اعمال استانداردهای مناسبی روی کد میشود و انسجامی ایجاد میکند که به تیمها در مسیر مقیاسبندی توسعه جاوا اسکریپت کمک خواهد کرد و این در عمل هدف اصلی استفاده از تایپ اسکریپت است.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- آموزش جاوا اسکریپت (JavaScript)
- مجموعه آموزشهای JavaScript (جاوا اسکریپت
- انواع پیشرفته در TypeScript — با مثال های کاربردی
- راهنمای جامع تایپ اسکریپت (Typescript) — از صفر تا صد
==