Folder Organization در React: Simplifying Chaos with a New Structure 🚀

مرهمی!
در دنیای مهندسی نرم افزار، ضرب المثلی مانند این وجود دارد که “سازمان پوشه ها با معماری نرم افزار متفاوت است”، من این را درک می کنم، اما با این وجود، دوست دارم ساختارهای مختلف را مطالعه کنم و مزایا و چالش های آنها را درک کنم.
بنابراین، من قصد دارم روشی را که اخیراً در پروژه های React خود پوشه ها را سازماندهی کرده ام با شما به اشتراک بگذارم.
برخی زمینه سازی ها
من از پس زمینه ای می آیم که به شدت تحت تأثیر C# (.NET) قرار گرفته است، جایی که استاندارد، حداقل در آن زمان (2016-2018)، همیشه MVC (Model-View-Controller) بود. در هر پروژه ای که برنامه به 3 لایه تقسیم شده است، تردیدی وجود ندارد:
مدل – اشیایی که در پایگاه داده ذخیره می شوند، که امروزه به آنها می گویند موجودیت ها.
چشم انداز – کلاس ها جنبه های بصری برنامه، شامل فرم ها، صفحات ورود، صفحه اصلی، هر چیزی که بصری بود، دروازه ای بود که اجزا و داده ها را به کاربران ارائه می کرد، به یک کنترلر متصل می شد و از اشیا استفاده می کرد (مدل ها، یا در معماری MVVM ViewModels) از داده ها
کنترل کننده – هافبک برنامه ها، مراقبت از اعتبارسنجی، قوانین تجاری، پایگاه داده دسترسی، مدل تجزیه شده، هدایت به بازدیدها و خوب، برنامه را کنترل کرد.
سازماندهی در پوشه ها بر اساس نوع
هر پوشه فایل ها را از یک لایه خاص ذخیره می کند. با گذشت زمان، لایه از خدمات و بسته به الگوی طراحی، مخازن.
در این معماری، فایل ها بر اساس نوع جدا می شدند و ساختاری کم و بیش شبیه به این پیدا می کردند.
src/
controllers/
LoginController
UserController
models/
LoginModel
UserModel
services/
LoginService
UserService
views/
LoginView
UserProfileView
هنگام مهاجرت به React در سال 2018، یک مؤلفه «واکنشی» را پیدا کردم که در بالای کلاسها ساخته شده بود.
با بسیاری
this
bind
constructor
this.setState({ ...this.state, count: this.state.count + 1 })
تصمیم گرفتم که از “MVC” در React استفاده کنم.
components/
LoginForm.js
models/
User.js
services/
userProfile.js
views/
UserProfile.jsx
فواید
تصمیم گیری در مورد مکان ایجاد هر فایلی آسان است.
اگر یک صفحه است، آن را در داخل ایجاد می کنید دیدگاه ها، اگر بخشی از ادغام آن باشد UI همانطور که در API، این هست یک سرویس.
اگر شیئی باشد داخلش نگه میدارم مدل ها و اگر یک جزء مشترک است، در داخل اجزاء.
چالش ها
با گذشت زمان، اندازه پوشه ها بسیار افزایش می یابد!
با React، داشتن کامپوننتهای زیادی رایج است (و توصیه میشود).
رابط کاربری از چندین بخش متحرک، با اندازههای مختلف تشکیل شده است که انعطافپذیر، سبک و مهمتر از همه، اجزای سازنده هستند.
با آن، یافتن فایلها دشوار است، حتی بدتر از آن، یافتن توابع، باید در یک پوشه بزرگ جستجو کنید و آنها را با هم مقایسه کنید.
اما بزرگترین مشکل این است که در حال حاضر، برای هر ویژگی جدید، باید X فایل جدیدی ایجاد کنید که در پوشه های مختلف پراکنده می شوند، پیدا کردن آنها دشوار است و اگر برنامه پوشش خوبی از تست های واحد نداشته باشد، حتی ایجاد تغییرات دشوارتر است
سازماندهی در پوشه ها بر اساس عملکرد
برای پرداختن به این موضوع، ساختار پوشه در مقالات و بحثها دوباره اختراع شده است.
این نشان می دهد که برنامه دیگر نباید به انواع تقسیم شود، بلکه باید بر اساس “ویژگی های” سیستم گروه بندی شود.
از فلسفه پیروی می کند
حذف یک ویژگی باید به آسانی حذف یک پوشه باشد.
فواید
فایلها سازماندهیشدهتر هستند، همه فایلهای داخل یک پوشه مستقیماً به هم متصل میشوند، ساختار به راحتی قابل پیمایش است مدولار از features
.
components/
button/
input/
features/
authentication/
Login.js
LoginForm.js
useAuth.js
AuthService.js
AuthSlice.js
profile/
Profile.js
UserProfile.js
ProfileService.js
چالش ها
فایل های به اشتراک گذاشته شده
- اجزای غیر جهانی
- رابط ها
- قلاب
فایل های به اشتراک گذاشته شده یک مشکل در ساختار features
زیرا اگر فایلی با بیش از یک ویژگی به اشتراک گذاشته شده باشد اما جهانی نباشد، تصمیم گیری در مورد محل زندگی آن دشوار است.
اگر جزء وجود داشته باشد UserAvatar
به اشتراک گذاشته شده توسط دو ویژگی، اگر ما تصمیم به قرار دادن آن در components
، به این معنی است که با گذشت زمان، این پوشه تمام اجزای غیر خصوصی برنامه را در خود جای می دهد.
و بزرگ خواهد شد و باز هم یافتن روابط بین اجزاء دشوار خواهد بود.
هر پوشه جدیدی که ایجاد می کنید، با گذشت زمان، اگر یک برنامه بزرگ باشد، رشد می کند و به هم ریخته می شود. پاستا بر حسب نوع.
علاوه بر این، اگر دارید مشخصات کاربر، تنظیمات کاربر و سایر ویژگی های مربوط به کاربر، آنها نیز با هم گروه بندی نمی شوند، اما در قسمت های مختلف برنامه آزاد خواهند بود.
یعنی اگر بخواهید همه موارد مربوط به کاربر را در برنامه حذف کنید، با حذف نمی توانید این کار را انجام دهید. فقط یکی پاستا
components/
userAvatar/
features/
profile/
Profile.js
UserProfile.js
ProfileService.js
settings/
Settings.js
UserSettings.js
پیشنهاد برای حل مشکلات
پس از چند سال و پروژهها، بحثها و بحثهای فراوان، تصمیم گرفتم یک رویکرد ترکیبی از پوشه به ویژگی، یا بهتر، پوشه به ویژگی، به نوع پیشنهاد کنم و یک پوشه جدید برای جهانی اضافه کنم. فایل ها.
من هم متوجه آن شدم features
در نهایت به یک محدودیت استثنایی برای بخش هایی از برنامه تبدیل شد که اگرچه کاربردی هستند، اما همیشه نیستند موجودیت ها کلان.
من تصمیم گرفتم یک مفهوم جدید (بسیار معروف و پرطرفدار در BackEnd) برای سازماندهی پوشه اضافه کنم دامنه.
ساختار پوشه بر اساس دامنه
من متوجه شدم که اقلام گروه بندی شده توسط نوع منجر به تعداد زیادی فایل در یک پوشه می شود و این منجر به شکستن گروه بندی مجاورت می شود.
بنابراین، من پیشنهاد می کنم که در سطوح بالاتر برنامه، یک استراتژی از پوشه به دامنه، جایی که دامنه بخشی از برنامه است که نشان دهنده a است وجود، موجودیت یا عملکرد، به منظور جلوگیری از انباشته شدن “اوایل” فایل ها که در نهایت ساختار پوشه را آلوده می کند.
و در سطوح کوچکتر، فقط در صورت لزوم، از رویکرد استفاده کنید پاستا بر حسب نوع.
assets/
domains/
/user
/components
UserAvatar.js
/enums
/features
/profile
/settings
/types
/hooks
global/
/components
/enums
/hooks
/routes
/store
/types
وقتی لازم نیست
هنگامی که فقط 1 فایل از یک نوع خاص در یک پوشه وجود دارد، به عنوان مثال:
domains/
/user
UserAvatar.js
/features
/profile
UserProfile.js
ProfileService.js
من از این دفاع می کنم که مثلاً پوشه کمتر از 2 فایل از نوع خاصی داشته باشد UserAvatar.js
، این ضروری نیست برای هر نوع یک پوشه برای قرار دادن 1 فایل واحد ایجاد کنید.
در این مورد حتی پوشه domains
تا زمانی که یک دامنه دوم برای برنامه وجود نداشته باشد، غیر ضروری خواهد بود، مانند:
src/
user/
UserAvatar.js
features/
/profile
UserProfile.js
ProfileService.js
ایده این استراتژی سیال بودن و استفاده از بهترین های هر دو جهان است.
- سازماندهی بر اساس نوع، زمانی که یک پوشه به “گروه بندی” دو فایل از یک نوع کمک می کند.
- سازمان توسط دامنه در سطوح بالا، برای ترویج حرکت سریع بین بخش های برنامه.
مقایسه/مرور پوشه ها آسان تر از مقایسه فایل ها است.
زمان ایجاد پوشه به نوع
وقتی یک پوشه حاوی دو فایل از یک نوع باشد.
این شماره یک پیشنهاد است، در صورتی که بخواهید آن را به 3 تغییر دهید تا تعداد پوشه ها کاهش یابد، گزینه ای نیز هست.
به عنوان مثال، اگر دامنه کاربر شروع به شامل تعداد زیادی هوک کند، مانند useUser.js، useUserPreferences.js، useUserSettings.js و غیره، ایجاد یک پوشه hooks برای نگه داشتن همه این فایل های مرتبط با هم مفید خواهد بود:
domains/
/user
/components
UserAvatar.js
UserBadge.js
/hooks
useUser.js
useUserPreferences.js
useUserSettings.js
/features
/profile
UserProfile.js
ProfileService.js
در این مورد، پوشه جدید کمک می کند تا ساختار دایرکتوری شفاف و سازماندهی شده باشد و یافتن فایل های مربوطه را در صورت نیاز آسان تر می کند و به شما امکان می دهد بخش ها یا انواعی را که برای جستجوی شما جالب نیستند (با کمک IDE) کوچک کنید. .
نتیجه
استراتژی پوشه به دامنه پیشنهادی یک روش ترکیبی است که با هدف متعادل کردن مزایای رویکردهای پوشه به نوع و پوشه به عملکرد انجام می شود.
با استفاده از آن، برنامه به دامنههایی تقسیم میشود که نشاندهنده موجودیتها یا عملکردها هستند و هر دامنه تنها در صورت لزوم بر اساس نوع تقسیم میشود.
انعطاف پذیری این مدل امکان تنظیم بر اساس نیازهای خاص پروژه و تیم را فراهم می کند.
سازماندهی پوشه ها و فایل ها یک هنر است و امیدوارم این پیشنهاد بتواند شما را برای یافتن استراتژی ایده آل برای پروژه های خود الهام بخشد.
هر استراتژی را که انتخاب می کنید، به یاد داشته باشید که هدف نهایی همیشه این است که کد را خواناتر، قابل پیمایش و نگهداری کنید.