جنبش 0deps: وابستگی‌های محلی و قراردادهای تغییرناپذیر

توسعه‌دهندگان نرم‌افزار اغلب صدها کتابخانه خارجی را نصب می‌کنند. فریم‌ورک‌های مدرن به هزاران وابستگی انتقالی (transitive dependencies) متکی هستند. این بدان معناست که اپلیکیشن شما کدهایی را از افراد ناشناس اجرا می‌کند.

این موضوع باعث ایجاد ریسک در زنجیره تأمین نرم‌افزار می‌شود.

هر وابستگی سطح حمله (attack surface) شما را افزایش می‌دهد. این وابستگی می‌تواند:

  • نقایص امنیتی ایجاد کند.
  • به هدفی برای حملات زنجیره تأمین تبدیل شود.
  • توسط نگهدارندگان رها شود.
  • رابط برنامه‌نویسی عمومی (public API) خود را تغییر دهد.
  • سازگاری با نسخه‌های قبلی (backward compatibility) را از بین ببرد.

جنبش 0deps یک سوال ساده می‌پرسد: چه می‌شود اگر اپلیکیشن شما فقط به کدهایی متکی باشد که خودتان کنترل می‌کنید؟

در مدل 0deps، شما وابستگی‌های ضروری را مستقیماً در مخزن (repository) پروژه خود قرار می‌دهید. دیگر آن‌ها را به صورت پویا در طول فرآیند ساخت (build) دانلود نمی‌کنید. هر آنچه برای اجرای اپلیکیشن لازم است، از ابتدا در مخزن باقی می‌ماند.

این رویکرد موارد زیر را فراهم می‌کند:

  • ساخت‌های بازتولیدپذیر (Reproducible builds).
  • اتکای کمتر به رجیستری‌های خارجی.
  • حسابرسی‌های امنیتی متمرکز.
  • پیش‌بینی‌پذیری بالاتر.

اصل اساسی این نیست که کد را ایستا نگه دارید. پیاده‌سازی‌ها و الگوریتم‌ها باید برای رفع باگ‌ها و بهبود امنیت تکامل یابند. آنچه پایدار می‌ماند، قرارداد عمومی (public contract) است.

هر کتابخانه یک رابط (interface) با طراحی دقیق ارائه می‌دهد. نمونه‌هایی از آن عبارتند از:

  • authenticate()
  • createSession()
  • verifyPasskey()

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

وقتی یک آسیب‌پذیری ظاهر می‌شود، معمولاً با دو مشکل روبرو هستید:

  1. رفع نقص.
  2. بررسی اینکه آیا به‌روزرسانی باعث از کار افتادن اپلیکیشن شما می‌شود یا خیر.

در معماری 0deps، مشکل دوم از بین می‌رود. شما پیاده‌سازی داخلی را به‌روز می‌کنید در حالی که API عمومی ثابت می‌ماند. اپلیکیشن شما بدون نیاز به تغییر در کد، به کار خود ادامه می‌دهد.

شما ادغام‌های خارجی را با استفاده از یک آداپتور داخلی ایزوله می‌کنید: Application -> Public Interface -> Adapter -> Implementation

اگر کتابخانه‌ای فردا ناپدید شود، شما فقط آداپتور را تغییر می‌دهید. هیچ بخش دیگری از اپلیکیشن شما از کار نمی‌افتد.

0deps نرم‌افزار را بی‌نقص نمی‌کند، بلکه ریسک‌های زنجیره تأمین را کاهش می‌دهد. این رویکرد از مشکلاتی مانند بسته‌های مخرب، هک شدن رجیستری‌ها و سردرگمی وابستگی (dependency confusion) جلوگیری می‌کند.

پروژه‌ها دهه‌ها عمر می‌کنند، اما کتابخانه‌ها و فریم‌ورک‌ها تغییر می‌کنند. با 0deps، اپلیکیشن شما بدون توجه به نحوه تکامل اکوسیستم، همچنان از همان قراردادهای پایدار استفاده می‌کند.

منبع: https://dev.to/fullagenticstack/movimento-0deps-dependencias-locais-contratos-imutaveis-e-seguranca-por-design-4coo