حسان امینی لو
حسان امینی لو
خواندن ۱۱ دقیقه·۹ ماه پیش

موقع انتخاب کردن Lib ها به چی باید توجه کنیم؟

۲-۳ سال پیش میخواستیم برای شرکت نیرو فرانت بگیریم. من باید با افراد مصاحبه می‌کردم. یه بنده خدایی اومد مصاحبه و توی جلسه Live code گفتیم میخوایم یه لیست رو از سرور بگیریم و نشون بدیم که یه قابلیت خیلی ساده برای Pagination هم داشته باشه.

استارت کار رو زد و پروژه جدید ایجاد کرد. خب وقتی یه پروژه React Native ایجاد میشه یه تعداد کتابخونه به صورت پیشفرض روش نصب میشه که خب اصطلاحا میگیم out of the box اینا رو داره. بعد برای دریافت دیتا ها از سرور رفت و axios رو نصب کرد.

برای UI یه کتابخونه دیگه اضافه کرد (فکر کنم MUI بود). برای فیلتر کردن آیتم ها یه کتابخونه دیگه نصب کرد. برای عکس های گالری یه کتابخونه دیگه نصب کرد... برای کلاس ها یه کتابخونه ی دیگه .... همینطوری مثل یه نفر که میره هایپر مارکت همه چیو از قفسه ها برمیداره شروع کرد به نصب کردن کتابخونه های مختلف! خیلی هاش رو من اصلا نشنیده بودم یا ندیده بودم که وجود دارن! واقعا برگام ریخته بود. تا وسطای کار پیش رفته بود که گفتم لطفا ادامه نده و تا همینجا کافیه.

مشکل اینجا بود که اون فرد انقدر به ابزار ها وابسته شده بود که دیگه عملا خودش هیچ کاری انگار نمیتونست انجام بده.

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


اصلا چرا پکیج جدید؟

آیا کاری که میخواید انجام بدید رو بدون پکیج هم میشه انجام داد؟ چه دلیلی داره که برای انجامش پکیج بخواد اضافه بشه؟ بذارید برای درک راحت تر براتون مثال بزنم.

فرض کنیم پکیجی که میخوایم نصب کنیم یک پکیج مثل lodash هست. این پکیج یه سری ابزار در اختیار ما قرار میده که مثلا بتونیم با array ها راحت تر کار کنیم. کارایی مثل فیلتر کردن و index گرفتن و مرتب کردن و کلی چیزای دیگه. خب بودن چنین کتابخونه ای میتونه کمک کنه ولی آیا بدون این کتابخونه میشه اینکارارو انجام داد؟ یا اگه این پکیج رو اضافه کنیم که ۲۰۰ تا کار انجام میده،‌ ما میخوایم از همه اون ۲۰۰ تا تابع استفاده کنیم یا استفاده مون محدود میشه به ۱۰ تا دونه از اون توابع؟ کاری به این نداریم که بعضی وقتا میشه به کمک tree-shaking حجم باندل رو کم کرد و فقط توابعی رو توی پکیج نهایی آورد که واقعا استفاده شدن. موضوع اینه که ارزشش رو داره؟

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

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

هزینه و مزیت (Cost and Benefit)

خب حالا دیگه تصمیم بر اینه که کتابخونه جدید اضافه بشه، به چه چیز هایی باید فکر کنیم؟

به طور کلی میتونیم این موارد رو در نظر بگیریم:

  • باندل سایز
  • پشتیبانی و Community
  • هماهنگی با بقیه اجزای سیستم (Compatibility)
  • وابستگی ها (Dependency)
  • هزینه یادگیری (Learning curve)
  • پرفورمنس (Performance)
  • داکیومنت ها (Documentation)

چندتا مورد دیگه هم هست که به نظرم تو دسته بندی خاصی قرار نمیگیرن ولی توضیح میدم.


باندل سایز

قبل اینکه دستور npm install یا yarn add رو بزنید، میتونید به کمک ابزار هایی مثل bundlephobia حجم شون رو چک کنید. مثلا اگه بین انتخاب ۲ تا کتابخونه مردد هستین، این میتونه گزینه خوبی باشه برای مقایسه و راحت تر کردن انتخاب مون.

برای نمونه من ۲ تا کتابخونه Formik و React hook form رو باهم مقایسه کردم:

قسمت های مهم رو هایلایت کردم. اول اون ۳ تا مورد کوچیک که اون بالاست داره میگه این کتابخونه قابلیت Tree-shaking داره. یعنی به کمک webpack میشه قسمت هاییش که توی پروژه استفاده نشده رو هرس کرد و ریخت دور که هجم باندل رو زیاد نکنه. خب این یه نکته مثبته. ✅

دوم اینکه side-effect ای نداره. یعنی API ها و ابزار هایی که این کتابخونه داره در اختیار شما قرار میده روی بقیه اجزای سیستم تون تاثیری نمیذاره که خب این خیلی نکته خوبیه ✅

سوم اینکه این کتابخونه آیا به کتابخونه های ریز و درشت دیگه ای وابستگی داره؟ به بیان دیگه وقتی شما این کتابخونه رو نصب میکنی همراه خودش چه چیزای دیگه ای نصب میکنه. خب طبیعیه که هرچی تعداد این dependency ها کمتر باشه بهتره. که خب اینجا میبینیم که صفر هست ✅

نکته بعدی در مورد حجم باندل اش هست. به صورت minimize میبینیم که حجمش چقدره، همینطور به صورت minimize + gzip. کلا رفرنسی از اینکه این عدد چقدر باید باشه وجود نداره یا نمیشه گفت چون کتابخونه های مختلف کارای مختلف میکنن. هرچی کمتر باشه ولی میدونیم که بهتره دیگه.


همینطور که مشخصه، پکیج formik در مقایسه با react hook form خیلی ضعف های بیشتری داره. مثلا اینکه پکیج اش ۸ تا dependency داره ❌

ولی همچنان tree shakable هست ✅

در مقایسه حجم پکیج هم مشخصا نسبت به react hook form سنگین تره ❌

یه نکته مهم: ما اینجا داریم در مورد dependency ها صحبت ‌میکنیم، بنابراین باید دقت کنیم بعضی از ابزار هایی که استفاده میخوایم بکنیم صرفا تو فرایند develop به ما کمک میکنن. بنابراین باید دقت کنیم همیشه که مثلا چیزایی مثلا TypeScript یا ESLint یا Prettier و امثال اینها رو حتما به صورت devDependency نصب کنیم که تاثیری روی باندل سایز ما نگذارن.



پشتیبانی و Community

بعضی کتابخونه ها هستن مثل یه چیزی که مثلا من نوشتم 😁 کلا به جز خودم و شااااید چندتا از دوستام کس دیگه ای ازش استفاده نمیکنه. این مدل کتابخونه ها تو اینترنت کم نیستن. اگه از این مدل ابزار ها بخوایم استفاده کنیم میدونیم که آخر و عاقبت خوشی نداره.

هر مشکلی یا سوالی یا چیزی پیش بیاد ما ناچاریم که ۰ تا ۱۰۰ اش رو خودمون انجام بدیم. پس برمیگردیم به همون نقطه ای که ازش شروع کردیم. اصلا چرا؟

قبل نصب بد نیست یه نگاهی به گیتهاب اون پروژه بندازید. ببینید چقدر issue باز داره و چندتا از issue ها بسته شدن. چقدر اون Contributer ها فعال هستن و سریع جواب میدن. یا چندتا star داره یا روی npm به صورت هفتگی چندبار دانلود میشه.


هماهنگی یا Compatibility و وابستگی ها (Dependencies)

این مورد خیلی سادس، کلا چقدر این کتابخونه با اپلیکیشن شما هماهنگه. مثال خیلی خیلی سادش این که شما هیچوقت نمیتونید یه پکیج vue رو توی پروژه React نصب کنید! یا خیلی قدیم تر ها یادمه خیلی پکیج هایی که با jQuery کار میکردن رو با کلی دنگ و فنگ میاوردیم توی React که کار کنه. خب چرااا؟؟ 😁

خب این موضوع که واضحه ولی واقعا قبل اینکه نصب کنیم مثلا بهتره که چک کنیم نسخه React این کتابخونه با نسخه ری-اکتی که ما داریم هماهنگ باشه. بعضی کتابخونه ها به خاطر اینکه قدیمی تر هستن مثلا با ری-اکت نسخه های بالاتر خوب کار نمیکنن.

همینطور بهتره که چک کنیم که کتابخونه ای که داریم اضافه می‌کنیم به جز پکیج اصلیش چه چیزای دیگه ای هم همراهش نصب میشه. طبیعتا هر چی تعداد این dependency ها کمتر باشه بهتره ولی اگر اینطور هم نبود و ما هم انتخاب دیگه ای نداشتیم، دست کم چک کنیم که این dependency ها با پروژه مون هماهنگی داشته باشن.


بحث Learning Curve

این موضوع از اون موضوعات به شدت مهمیه که شاید خیلی اوقات ما هم کمتر بهش فکر می‌کنیم. به نظرم اصلا یکی از مهم ترین شاخص های انتخاب یه کتابخونه یا فریمورک موضوع اینه که توی تیم کی اینو بلده از قبل و یا یاد گرفتنش چقدر زمان میبره؟

اصلا یکی از دلایلی که میریم سمت کتابخونه های خیلی شناخته شده تر اینه. مثلا شما اگه میخواید سیستم Router به پروژه اضافه کنید تقریبا شاید ۵-۶ تا انتخاب داشته باشید ولی میدونیم که اکثر توسعه دهنده ها ۱-۲ مدل از اونا رو بلدن. انتخاب یه کتابخونه یا فریم ورک که بقیه از قبل باهاش آشنا باشن بحث به شدت مهمیه.

یکی از counter argument های خیلی مهم برای اینکه خودمون نیایم راه حل های عجیب و غریب بزنیم یا خودمون برای خودمون یه فریمورک (در سطح کل پروژه) بسازیم از صفر همین موضوعه. کسی که میخواد بعدا با ما کار بکنه و توی تیم اضافه بشه احتمال اینکه مثلا قبلا با react router dom یا حتی خود React کار کرده باشه خیلی خیلی خیلی بیشتره تا اینکه بخوایم همه چیز رو از اول خودمون نوشته باشیم.

این یعنی هزینه onboarding افراد جدید به پروژه رو داریم بالاتر می‌بریم.

توی انتخاب هامون هم این موضوع مهمیه چون که بعضی از کتابخونه ها یادگیریشون بسیار هزینه بر هست. بنابراین اینجا ما یک trade-off داریم که باید در نظر بگیریم. برای نمونه اگر میخوایم برای data visualization از یه کتابخونه استفاده کنیم باید سعی کنیم چیزی باشه که یا افراد دیگه ی تیم اون رو بلد باشن و یا یاد گرفتن اون کتابخونه جدید براشون کار ساده تری باشه.

تو چنین شرایطی انتخاب یه کتابخونه مثل D3 میتونه یه ریسک بزرگ باشه چون هزینه توسعه رو به شدت بالا میبره و سرعت رو میاره پایین. درسته که توی performance شاید خیلی خیلی با اختلاف زیادی نسبت به بقیه گزینه مناسب تری باشه ولی ما چی بدست میاریم و چی از دست میدیم؟ همیشه این موضوع رو باید گوشه ذهنمون داشته باشیم. در مواقعی که پروژه ها ددلاین های محدود دارن باید چیزی رو انتخاب کنیم که بتونیم سریع توسعه بدیم و کار رو برسونیم.

از طرف دیگه اینکه اون کتابخونه چقدر community فعالی داره یا چقدر داکیومنت های خوبی داره هم توی فرایند learning curve اش مهمه و در انتخابش تاثیر گذاره. که البته جلوتر راجع بهش صحبت میکنم.


پرفورمنس (Performance)

البته که شاید خیلی مواقع دلیل اصلی ما (یا شاید یکی از دلایل ما) برای انتخاب کتابخونه هایی که مطرح تر هستن همین بحث Performance هست. میدونیم که هر چه قدر اون کتابخونه جامعه فعال تری داشته باشه و تعداد کاربران بیشتری داشته باشه یعنی edge case های بیشتری رو تونسته هندل بکنه . احتمال اینکه اون وسط یهو یه چیز خیلی تابلویی بترکه خیلی خیلی خیلی کمتر هست!

این توی کتابخونه های بزرگ کاملا موضوع طبیعی ای هست چون شما تصور کن یه چیزی مثل bootstrap یا react router dom یا react query بسیار بسیار محبوب هستن. از طرفی اگر کسی issue خاصی روی اینا پیدا کنه سریع تر گزارش میشه و به خاطر community فعالی که دارن سریع تر هم فیکس میشن و کتابخونه ها سلامت تر هستن به طور کلی.

موضوع پرفورمنس هم توی همین قاعده بهش نگاه کنیم. کتابخونه های معروف و مطرح که کاربران بیشتری دارن پس احتمالا اپلیکیشن های خیلی زیادی هم دارن ازشون استفاده میکنن بنابراین خیلی پولیش شده تر و سلامت تر و بهینه تر کار میکنن. برای مقایسه من کتابخونه a رو با کتابخونه b مقایسه نمیکنم،‌ اینطور بهش نگاه میکنم که اگر من خودم میخواستم یه ابزار شبیه اونایی که نام بردم بنویسم چقدر مشکل performance داشتن؟ قطعا چیزی که من می‌نویسم نمیتونه با یه چیزی که شاید ده ها توسعه دهنده داره رقابت کنه.

البته ناگفته نماند که من حرفم این نیست که کلا توسعه ابزار های local برای پروژه خودمون رو کلا کنار بذاریم، بعضی وقتا شاید حتی چاره ای نداشته باشیم جز اینکه خودمون ابزار خودمونو بنویسیم. حرفم اینه که تا جایی که اون trade-off بیشتر به سمت منفعت داشتن شون (با در نظر گرفتن تمام نکاتی که گفتم)‌ سنگینی میکنه، توسعه یه ابزار توسط تیم خودمون قطعا کار عاقلانه ای نیست.


داکیومنت (Documentation)

همه چیزایی که تا حالا گفتم خیلی مهم بودن! ولی داکیومنت های یه کتابخونه شاید اولین چیزی هستن که شما رو با اون ابزار آشنا میکنن. در آینده اگر هم بخوایم از اون کتابخونه ها استفاده کنیم همین داکیومنت ها قراره راهنمای ما باشن برای جایی که به مشکل بخوریم‌، کار خاصی بخوایم انجام بدیم و ...

داشتن یه داکیومنت خوب بهمون کمک میکنه که هم هزینه یادگیری اون کتابخونه رو کاهش بدیم، هم اگر به مشکلی خوردیم بتونیم راحت تر حلش کنیم، هم از همه مهم تر:

قبل از نصب اون کتابخونه مطمئن بشیم که جواب مساله ما این ابزار هست یا نه!

یهو نریم تند و تند کتابخونه ها رو اضافه کنیم و از ۱۰۰ اون کتابخونه فقط از ۵ درصدش استفاده کنیم. این کار عاقلانه ای نیست.

اگرم میخوایم بدونیم که این کتابخونه داکیومنت های خوبی داره یا نه،‌ ببینیم چطور به سوالاتی که ما داریم جواب میده؟ چقدر راحت به چیزی که میخوایم میرسیم؟ اصلا فرایند ستاپ اولیه اون کتابخونه رو چقدر خوب توضیح داده؟



موارد دیگه

این موارد به نظرم نیومد که توی Category خاصی قرار بگیرن. برای همین مدل لیستی من بهشون فقط اشاره میکنم:

  • بعضی کتابخونه ها یک Licence خاصی دارن که ممکنه براتون مشکل ساز بشه. البته ما تو ایرانیم 😁
  • بد نیست بعد اینکه کتابخونه جدید رو اضافه کردین یه بار audit کنید ببینید آسیب پذیری عجیبی نداشته باشه.
  • اجازه ندید توی پروژه تون پکیج هایی اضافه بشن که صرفا و صرفا به خاطر جوگیر شدن بودن. مثلا همه یهو هایپ شدن برن سمت یه چیزی. شما تصمیم درست رو بگیرید.
  • بلند نظر باشید،‌ این رو بدونیم که پروژه ای که روی یه کتابخونه یا فریمورک بنا میشه قراره شاید سال ها روی اون ریل بره جلو پس توی انتخاب تون خیلی دقت کنید.
  • اگه پروژه تون TypeScript هست چک کنید حتما پکیج تون هماهنگ باشه باهاش.









data visualizationتوسعه دهندهری اکتnode modules
برنامه نویس از جلو
شاید از این پست‌ها خوشتان بیاید