اشتراک کد بین پروژه‌ها | معرّفی Bit.dev

بسم الله الرّحمن الرّحیمسلام به همه!در مورد راهکارهای مختلف اشتراک کد بین پروژه‌های مختلف مطالعه می‌کردم. به مقاله‌ای برخورد کردم که یکی از سازندگان bit.dev نوشته بود. مقاله‌شون برام جالب بود و می‌خواستم خلاصه‌اش رو نگهداری کنم. با خودم گفتم چه جایی بهتر از ویرگول ? و تصمیم گرفتم اوّلین پست خودم رو در اینجا بنویسم.لینک مقاله‌ی اصلی برای دوستانی که میخوان اصل ماجرا رو بخونن ? https://www.smashingmagazine.com/2018/04/sharing-code-between-projects/ ضمناً دوستانی که این مطلب رو می‌خونن باید آشنایی کلی با فریم‌ورک‌هایی مثل React، Vue.js یا Angular داشته باشند.ایشون در ابتدا به چالش جدی اشتراک کد بین پروژه‌های مختلف اشاره می‌کنه و از اهمّیت موضوع میگه. مثلاً میگه حدود ۳۰٪ کدهای پروژه‌ها، کپی و پیست از روی بقیه پروژه‌هاست! یا اینکه ۵۰٪ کدهای موجود در گیتهاب کپی همدیگه است! مثلاً فقط یک تابع isString در ۱۰۰۰۰ ریپازیتوری توی گیتهاب تکرار شده (هر کس برای خودش پیاده‌سازی یا کپی کردش).حالا چند راهکار به ذهنشون رسیده که مشکل رو حل کنند.ایجاد ریپازیتوری‌های مختلف به ازای هر کامپوننتخوب این روش در ابتدا خیلی خوب به نظر میاد. ولی وقتی در عمل استفاده بشه مشکلاتش فهمیده می‌شه. مثلاً وقتی تعداد کامپوننت‌ها زیاد بشه مدیریت این همه ریپازیتوری وحشتناکه. اینکه ریپازیتوری‌ها جدای از پروژه‌ی اصلی هستند خودش یک معضله! کسی که در تیم می‌خواد کامپوننت رو ویرایش کنه باید بره ریپازیتوری رو جداگانه clone کنه، دسترسی هم داشته باشه به ریپازیتوری! (فرض کنید ۱۰۰ تا ریپازیتوری مختلف داشته باشیم و بخوایم به همه‌ی اعضای تیم هم دسترسی بدیم!!!). این قضیه سرعت توسعه رو خیلی کند میکنه. مشکل بعدی اینه که راحت نیست همه اعضای تیم بفهمن چه کامپوننت‌هایی اصلاً وجود دارن و قبلاً ساختیمشون!استفاده از Lernaابزاری وجود داره به اسم Lerna که هدفش مدیریت چند ریپازیتوری با همدیگه است. حتماً کتابخونه‌هایی مثل Angular رو دیدین که ماژول‌های مختلفش رو در ریپازیتوری‌های مختلف گذاشتن. ولی همه با هم یک چیز رو تشکیل می‌دن. به هرکدوم از این ریپازیتوری‌های مجزّا یک monorepo گفته میشه. lerna هم برای مدیریت همیناست. مثلاً شما می‌تونین چندین ریپازیتوری مختلف رو با هم در یک ساختار پوشه‌بندی به شکل زیر در lerna مدیریت کنین:my-lerna-repo/ package.json packages/ package-1/ package.json package-2/ package.jsonخوب همون طور که مشخّصه خیلی از مشکلاتی که در قسمت قبل گفتیم به قوّت خودش باقیست! ولی خوب در مدیریت کمکمون می‌کنه. البته این هم مشکلات خاص خودش رو داره. مثلاً ما فقط برای اشتراک کد بین پروژه‌هامون مجبوریم کل ساختار پروژه‌مون رو طبق فرمایشات lerna پیش ببریم! البته lerna در جای خودش و برای کاربرد خودش خیلی هم خوبه! ولی اینکه فقط به خاطر اشتراک کامپوننت‌ها بیاییم از این روش استفاده کنیم چندان جالب نیست.کتابخانه‌های مشترکدر این روش میان یک ریپازیتوری مشترک میسازن و همه‌ی کامپوننت‌ها رو می‌ریزن توی همون یکی! و به عنوان یک کتابخونه‌ی مشترک بین پروژه‌ها استفاده می‌کنند.خوب این روش هم چندان جالب نیست به چند دلیل:این کتابخونه به مرور رشد می‌کنه و خیلی بزرگ می‌شه، و توی هر پروژه‌ای که استفاده بشه سربار زیادی ایجاد می‌کنه. مثل این می‌مونه که به خاطر جابجا کردن یک پاکت نامه بریم یک تریلی بیاریم! (به خاطر استفاده از ۲تا کامپوننت مجبوریم کتابخونه‌ای که ۱۰۰تا کامپوننت داره رو اضافه کنیم به پروژه).هر پروژه‌ای که کامپوننت‌ها رو لازم داشته باشه خیلی درگیر این کتابخونه می‌شه. ممکنه حتّی کدهای این کتابخونه با اون پروژه در هم بپیچه و نشه در آینده کلا این کتابخونه رو از پروژه جدا کرد!برای اینکه تک تک کامپوننت‌ها رو اعضای تیم بدونن چیه و چه جوری میشه استفاده کرد باید یه عالمه زحمت بکشیم و درست و حسابی مستندسازی‌شون کنیم.حتّی کتابخونه‌های خیلی معروف جاوااسکریپت مثل lodash آروم آروم دارن به این سمت میرن که تابع‌های مختلفشون به صورت مجزّا از طریق npm قابل استفاده باشه.استفاده از git submoduleیکی از امکانات گیت این است که یک ریپازیتوری می‌تواند زیرپوشه‌ای از یک ریپازیتوری دیگر باشد. بنابراین می‌توان از کدهای یک ریپازیتوری در ریپازیتوری دیگر استفاده کرد.به این قابلیت git submodule می‌گن.این هم آخر قصّه نبود. چرا که submodule در گیت فقط روی برنچ master کار می‌کند، و باز هم سرعت توسعه را کند می‌کند. این شد که Bit متولّد شد!بیت متولّد می‌شودسازندگان بیت چیز زیاد پیچیده‌ای نمی‌خواستند! فقط می‌خواستند کامپوننت‌ها و ماژول‌ها رو از پروژه‌ها مستقل کنند، در فضایی ابری نگه داری کنند و در هر پروژه‌ای که خواستند از اون‌ها استفاده کنند. همین ?دیدگاه سازندگان بیتدر ساخت بیت چند دستورالعمل از همون ابتدا مد نظر بود و خیلی براشون مهم بود ساخت بیت بر این اساس باشه (برای خودم جالب بود):در عین اینکه کامپوننت‌ها باید مستقل از پروژه باشند، نباید لازم باشه به ازای هر کامپوننت ریپازیتوری مجزّایی ساخته بشه یا محیط تست و build اون پیکربندی بشه.توسعه‌ی کامپوننت باید دوطرفه باشه، یعنی در هر پروژه‌ای که بودیم باید بتونیم کامپوننت‌های مختلف را همان‌جا ویرایش کنیم، و بعد باید سایر پروژه‌ها sync بشه.مدیریت و اشتراک‌گذاری کامپوننت‌ها باید ساده باشه. باید همه‌ی اعضای تیم اطّلاعات لازم هر کامپوننت رو خیلی خوشگل و گرافیکی ببینند.بیت چگونه کار می‌کند؟روند کاری بیت در سه مرحله خلاصه می‌شه:اوّل باید به بیت بگیم کدوم قسمت از کد و کامپوننت‌هامون رو می‌خواهیم اشتراک‌گذاری کنیم. بعد بیت این قسمت‌ها رو در پروژه‌های مختلفی که به اشتراک گذاشته شده ردگیری می‌کنه و تغییراتشون رو ثبت می‌کنه.بعد میتونین version این کامپوننت‌ها رو هم مشخّص کنین، بعد بیت به صورت خودکار درخت وابستگی (depenency tree) فایلی و پکیجی رو تشخیص میده و ثبت میکنه. (خیلی پیچیده شد؟ نگران نباشین. منظورشون اینه که بیت نگاه می‌کنه چه فایل‌های دیگه یا پکیج‌هایی رو درون کامپوننت خودتون import کردین و اون‌ها رو ثبت می‌کنه. همین ?)نهایتاً کامپوننت‌ها رو به فضای ابری بیت (یا حتّی روی سرور خودتون) می‌فرستید. این طوری همه‌ی اعضای تیم می‌تونن کامپوننت‌ها رو ببینند، و مثل هر پکیج دیگه‌ای با npm یا yarn نصبشون کنند.بنابراین با استفاده از بیت اصلاً لازم نیست برای اشتراک کامپوننت‌ها ریپازیتوری جدیدی بسازید! یا اینکه کدتون رو تکه تکه کنید و...البته قسمت قشنگش اینجاست که با Bit می‌تونید کامپوننت‌ها رو در پروژه‌های دیگه import کنید. و از اون جایی که بیت این کامپوننت‌ها رو در بین پروژه‌های مختلف ردگیری می‌کنه در هر پروژه‌ای که بودید و این کامپوننت رو تغییر دادین sync میشه و همه‌ی پروژه‌های دیگه‌تون با کامپوننت جدید آپدیت خواهند شد. با روند کاری سریع و توزیع‌شده‌ای که Bit داره دیگه مشکلات اذیت‌کننده‌ی مربوط به دسترسی هم نداریم، و روی هر پروژه‌ای که باشیم می‌تونیم کامپوننت‌ها رو واسه‌ی همه‌ی پروژه‌ها آپدیت کنیم.ممنون از اینکه این پست رو تا اینجا مطالعه کردین، یا اینکه فقط اسکرول کردین و اومدین ببینید آخرش چی می‌شه! امیدوارم به دردتون خورده باشه.