مهرداد
مهرداد
خواندن ۵ دقیقه·۳ سال پیش

بازنشستگی کتابخانه Moment.js


اگر برنامه نویس جاوا اسکریپت هستید، به احتمال زیاد با کتابخانه Moment.js آشنایی دارید یا حداقل نام آن را شنیده اید. Moment.js معروف‌ترین کتابخانه برای کار با تاریخ و زمان در زبان برنامه نویسی جاوا اسکریپت است. در زمان نگارش این مقاله، تعداد دانلود هفتگی این کتابخانه (از سایت NPM) تقریبا 12 میلیون دانلود در هفته است! اما این پروژه به دلیل مشکلاتی که در طراحی دارد، توسط توسعه دهندگان آن بازنشسته شده است. اگر وارد سایت Moment.js شوید، در صفحه وضعیت پروژه، دلایل بازنشسته کردن پروژه را خواهید دید. در ادامه این دلایل را بررسی خواهیم کرد.

We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done.

source: https://momentjs.com/docs/#/-project-status/

دلایل بازنشسته کردن پروژه:

برخی از دلایلی که برنامه نویسان Moment.js در سایت رسمی این پروژه قید کرده اند:

  • تغییرپذیر بودن (Mutable) اشیا

تغییرناپذیری (Immutability) اشیا، یعنی اینکه بعد از ساخته شدن یک شئ، نتوان فیلدهای آن را دستکاری کرد. در واقع شئ به حالت فقط-خواندنی در می‌آید. این ویژگی در بسیاری از مواقع مطلوب است (مخصوصا هنگام کار کردن با فریمورک های جاوااسکریپتی مانند Angular, React و غیره).
اشیا Moment تغییرپذیر هستند. شما به سادگی میتوانید بعد از ساخته شدن یک شی Moment، مقادیر آن را تغییر دهید.

  • پشتیبانی نکردن از Tree-Shaking

کتابخانه Moment.js از Tree-shaking پشتیبانی نمی‌کند. همین موضوع باعث می‌شود که همه کد این کتابخانه در خروجی برنامه شما کپی شود، حتی اگر به بخش کوچکی از این کتابخانه نیاز داشته باشید. یک شئ Moment دارای دهها متد است که به احتمال زیاد به بسیاری از آنها نیاز ندارید.

«درخت تکانی» یا Tree-shaking یک تکنیک برای حذف کدهای استفاده نشده در برنامه های جاوااسکریپتی است. ابزارهایی مانند WebPack، به کمک این روش کدهای استفاده نشده در برنامه را تشخیص می‌دهند و آنها را در خروجی خود کپی نمی‌کنند.
  • اندازه

اندازه (minify شده) این کتابخانه حدود 60 کیلوبایت است. اگر نیاز به تقویمی غیر از میلادی دارید، باید پلاگین های مربوطه را نیز نصب کنید. برای مثال اگر نیاز به کار کردن با تاریخ شمسی دارید، باید moment-jalali را نیز نصب کنید. حجم این پلاگین حدودا 35 کیلوبایت است که به همراه حجم کتابخانه Moment.js جمعا 95 کیلوبایت می‌شود که حجم قابل ملاحظه ای است.

  • عدم پشتیبانی مناسب از Intl API

کتابخانه Moment.js برای Localization و محاسبات مربوط به Time Zone به فایل های اضافه نیاز دارد. این فایل ها اندازه نهایی برنامه شما را ده‌ها کیلوبایت بیشتر می‌کند. برای مثال اگر نیاز به پشتیبانی از Time Zone دارید، باید فایل moment-timezone-with-data-10-year-range.min.js که حجم Minify شده آن حدود 40 کیلوبایت است را به پروژه خود اضافه کنید. با توجه به اینکه Intl API در مرورگرهای امروزی و همچنین Node.js پشتیبانی می‌شود، کتابخانه های جدید، بدون کمک گرفتن از این فایل ها، عملیات Localization و یا محاسبات Time Zone را انجام می‌دهند.

آیا نمی‌شود این مشکلات را رفع کرد؟!

حتما می‌شود، اما به گفته برنامه نویسان Moment.js، اگر بنا باشد که این تغییرات روی طراحی کتابخانه صورت بگیرد، نسخه جدید این کتابخانه باید مجددا از اول طراحی شود و در آن صورت با نسخه فعلی سازگار (Backward compatible) نخواهد بود. به همین خاطر تصمیم توسعه دهندگان بر این شده که توسعه پروژه را متوقف کنند.

Creating a "Moment v3" that was immutable would be a tremendous undertaking and would make Moment a different library entirely. Since this has already been accomplished in other libraries, we feel that it is more important to retain the mutable API.

source: https://momentjs.com/docs/#/-project-status/


آیا باید همچنان از کتابخانه Moment.js استفاده کنم؟

بهتر است استفاده نکنید. این پیشنهاد تیم توسعه دهنده این کتابخانه است.

We recognize that many existing projects may continue to use Moment, but we would like to discourage Moment from being used in new projects going forward. Instead, we would like to recommend alternatives that are excellent choices for use in modern applications today.

source: https://momentjs.com/docs/#/-project-status/

اگر نیازی به تقویم شمسی، هجری-قمری و یا چینی! در پروژه خود ندارید، از Moment استفاده نکنید. اما چالش زمانی شروع می‌شود که نیاز به انجام تبدیلات تقویمی و یا انجام محاسبات در تقویم های شمسی یا قمری دارید. برای مثال می‌خواهید 25 روز شمسی را به تاریخ 1399/12/20 اضافه کنید. در اینصورت احتمالا گزینه های اندکی برای جایگزینی Moment.js دارید!

چه گزینه های دیگری دارم؟

کتابخانه های جاوا اسکریپتی دیگری هم وجود دارند که محسبات تاریخ را انجام می‌دهند. از جمله:

این کتابخانه ها مشکلات Momemt.js را ندارند، اما همه آنها یک مشکل مشترک دارند: پشتیبانی نکردن از تقویم هایی به غیر از تقویم میلادی. این موضوع برای برنامه هایی که با تاریخ هایی به غیر از میلادی سرو کار دارند موضوع مهمی است.

البته کتابخانه Luxon می‌تواند تاریخ میلادی را به سایر تقویم‌ها تبدیل و نمایش دهد اما نمی‌تواند محاسبات تقویمی را در آن تقویم‌ها انجام دهد(برای مثال نمی‌تواند 6 روز را به یک تاریخ شمسی اضافه کند).

کتابخانه JS-Sugar

واقعیت این است که زبان جاوا اسکریپت در کار کردن با تاریخ ضعیف است! شئ استاندارد Date فقط از تاریخ میلادی پشتیبانی می‌کند. Intl API هنوز به بلوغ نرسیده. البته خوشبختانه این API تبدیلات بین تقویمی (مثلا میلادی به شمسی) را انجام می‌دهد اما محاسباتی مانند جمع و تفریق را انجام نمی‌دهد.

کتابخانه JS-Sugar برای رفع این مشکلات طراحی شده است. از ویژگی‌های این کتابخانه می‌توان به موارد زیر اشاره کرد:

  • وابسته نبودن به یک «تقویم» خاص، حتی میلادی (مستقل از تقویم بودن)
  • امکان پیاده سازی تقویم‌های جدید (سه تقویم میلادی، هجری-شمسی و هجری-قمری از قبل پیاده سازی شده اند)
  • پشتیبانی از Time Zone
  • پشتیبانی از Localization
  • استفاده از Intl API برای Localization و محاسبات Time Zone
  • پشتیبانی از Tree-Shaking
  • اندازه کوچک
  • توسعه پذیر بودن (امکان پیاده سازی تقویم و Locale توسط برنامه‌نویس و منتشر کردن آنها برای استفاده دیگران)

در حال حاضر این کتابخانه در حال توسعه است و به زودی نسخه اولیه آن منتشر می‌شود. در مقالات بعدی شما را بیشتر با این کتابخانه آشنا خواهم کرد.




مقالاتی که تا کنون در رابطه با کتابخانه جاوااسکریپتی JSS-Date منتشر کرده ایم:


ریپازیتوری پروژه (جهت ثبت باگ و درخواست افزودن قابلیت‌های جدید):
https://github.com/js-sugar/date

مستندات پروژه:
https://js-sugar.github.io/date

javascripttime
برنامه نویس و مشاور فریمورک انگولار
شاید از این پست‌ها خوشتان بیاید