المقدمة

أحيانا كتير بنشوف أنماط مختلفة من كتابه الكود وبنشوف الأنماط دي كتير في شغلنا اليومي وبنستخدمها كمبرمجين من غير ما نعرف ال cost بتاعها في الخلفية،  وواحدة من الأنماط دي هي barrel file طب يعني ايه barrel file وهل هو صالح للمشروع أو لا ؟ 🤔 دا اللي هنعرفه في المقال ان شاء الله .


ماذا يعني barrel file ؟

ال barrel file عباره عن ملف واحد في الأغلب index.js او index.ts وهدفه الوحيد إنه يجمع ال exports الي في الملفات الأخرى الي بتكون في نفس ال folder يعني علي سبيل المثال

project/
├── components/
│   ├── index.ts          # Barrel file
│   ├── Button.ts
│   └── Modal.ts

ودا بيكون المحتوى بتاعه في الأغلب

// index.ts
export { default as Modal } from "./Modal"
export { default as Button } from "./Button"

بعد ما عرفنا ايه هو ال barrel file خلينا نشوف ايه المشاكل الي ممكن يسببها ال barrel file


Circular import ؟

تخيل معايا واني حبيت استخدم ال Button component داخل ال Modal component وبالتالي شكل ال Modal component الجديد هيكون كالتالي

// Modal.tsx

import { Button } from "./index"; // ❌ circulare import

export default function Modal() {
  return <div>
    <Button />
    rest Modal component …
</div>;
}

هنا بتحصل مشكلة ال circular import ودا لإنه ملف ال index.js بيشاور علي ال Modal وال Button معاً وال Modal بيشاور علي ال index.js وال index.js بيشاور علي Button وال Modal معاً وهكذا إلى ما لانهاية .وحل حاجة زي كدا اننا نعمل import ل ال Button component مباشرة مش من ال barrel file.

import { Button } from "./Button"; // good

export default function Modal() {
  return <div>
    <Button />
    Modal Component ...
</div>;
}

طب كدا عرفنا ازاي ممكن نتجنب ال circular import، لكن مش هي دي المشكله الوحيده الي بتسببها ال barrel file .


Development speed 

إستخدمنا ل ال barrel file بيبطئ بشكل كبير سرعة التطبيق أثناء ال development ودا بيحصل لأنه أي module بيحاول يستدعي ال barrel file  (اللي هو هنا في حالتنا index.js) بيحصل وإنه ال js بتحمل كل ال modules الي جواه حتي لو هنستخدم منها module واحد بس، ولحد هنا ممكن الموضوع ميأثرش علي التطبيق لانه عدد ال modules الي جوا  ال barrel file مهما كان كبير فهو عدد محدود، لكن المشكلة بتظهر بسبب إنه ال modules الأخرى (واللي ممكن منكونش محتاجنها في ال module الحالي الي شغالين فيه لكن اتعملها import بسبب ال barrel file) احتمال تكون بتعمل import ل external packages وال external packages دي بتعمل ل import  ل external packages تانيه وهكذا،  فنلاقي إنه حصل استدعاء ل modules و packages في أماكن غير مستخدمة فيها  ودا الي بيخلي عملية ال development بطيئة .


استخدامات ال barrel files ؟

واحدة من استخدامات ال barrel file هي اثناء إنشاء ال library ودا لانه ال library makers لازم يحددوا one entry point هي الي يقدر مستخدموا ال package انهم يعملوا استخدام ال package من خلالها  ودي بتكون في ال filed الي اسمه main في فايل ال packge.js اثناء انشاء ال package ودي ببساطه بتقول إنه  داخل الملف دا فيه كل ال exports الخاصة ب ال package واللي ممكن أي مستخدم ل ال package يعمل استدعاء منها ومتسمحش انه يحصل استدعاء لأي modules أخرى .

وهنا بنكون رجعنا تاني لاحتمالية حدوث ال circular import والي اتكلمنا عنها فوق ولكن حلها بسيط وإننا نستخدم eslint plugin اسمها no-cycle، كمان في بعض ال tools الي بتساعدك تشوف circular import  في المشروع بشكل visual اسمها madge.طب كدا احنا تجنبنا حدوث ال barrel file في مشروعنا ازاي ممكن نتعامل مع ال barrel files اللي بتكون مفروضه علينا من مكتبات خارجية ؟!


Barrel file on external packages

مهندسين  next.js  بيعالجوا مشاكل ال barrel file الي بتسببها مكتبات خارجية عن طريق flag اسمه  optimizePackageImports والي بيكون موجود داخل ملف ال next.config.js

module.exports = {
  experimental: {
    optimizePackageImports: ["my-lib"]
  }
}

ودا كل الي بيعمله إنه بيروح يعمل map لكل ال import الي بتستخدم ال  barrel file خارجي ويخليها تستخدم ال module file مباشراً .


في الختام

في المقال دا تناولنا نمط من أنماط ال software وهو ال barrel files وعرفنا متى نستخدمها وما هي ال tools اللي ممكن تساعدنا علشان نتجنب المشاكل اللي ممكن تسببها، دمتم سالمين وإلى اللقاء في مقال آخر.