زمان كانت ال scripts صغيرة و بسيطة بس مع الوقت بدأت ال scripts دي تبقي more complex و حجمها بقي كبير، عشان كدا كنا لازم نشوف طريقة ننظم بيها الكود بتاعنا بحيث يكون سهل القراءة و التعديل عليه فيما بعد و كانت الطريقة دي هي أننا بدل منخلي كل الكود في ملف js واحد بس، هنفصله في أكتر من ملف و دا الي بنسميه code splitting
كل file من ال files الصغيرة دي بنسميه module
و بيكون جواه كود معين و عشان نعمل ال code splitting دا كنا بنستخدم حاجه اسمها module system
زي AMD, UMD, CommonJS
لحد ما ال ES6 نزلت و نزل معاهاstandard بيعمل موضوع ال Modularity ده عن طريق ال exports/imports
أو ال language level module system
ال module ما هو إلا ملف js عادي ولكن فيه features معينة و كمان ال browser بيتعامل معاه بطريقة معينة. إذا في فرق بين ال module script و ال regular script و الفروقات دي هي
# | Regular script | Module script | ||
---|---|---|---|---|
Protocol | local file & Http & Https | Https & live-server | ||
Extension | js. | js. أو mjs. أو mjs.js. | ||
Type Attribute | text/javascript | module | ||
Default Mode | Sloppy mode | Strict mode | ||
Scope | Global Scope | Module-Level Scope | ||
value of this keyword | window object | Undefined | ||
import.meta object | ❌ | ✔ | ||
Execution Time | sync | deferred & async |
تعالي نشرح الجدول دا واحده واحده.
# | Regular script | Module script | ||
---|---|---|---|---|
Protocol | local file & Http & Https | Https & live-server |
- ال regular script : بيشتغل علي ال local file Protocol و ال HTTPS Protocol وال HTTP Protocol
- ال module script : بيشتغل علي ال Https Protocol و ال live server بس
# | Regular script | Module script | ||
---|---|---|---|---|
Extension | js. | js. أو mjs. أو mjs.js. |
- ال regular script : ال extenstion بتاعه بيكون
.js
زي كدا - ال module script : ال extension بتاعه بيكون
.js
أو.mjs
او.mjs.js
regularScript.js
moduleScript.js OR moduleScript.jsx OR moduleScript.mjs.js
# | Regular script | Module script | ||
---|---|---|---|---|
Type Attribute | text/javascript | module |
- ال regular script بيكون ليه
type="text/javascript"
بشكل افتراضي (by default) فمفيش داعي أكتبه - ال module script : بستخدم معاه
type="module"
و دا عشان أعرف المتصقح أن ملف ال js نوعه module
أنا لما باجي اعمل module جديد فلازم أعرف المتصفح ان الملف دا عبارة عن module [مش regular script] و دا بيتم عن طريق اني بضيف type="module" زي كدا
<script src="..." type="module"></script>
في طبعا متصفحات مش بتفهم ال type=module
[ يعني مش بتدعم ال js modules ] و بالتالي فهي هتتجاهل الملف كله ودا لان ال type بتاعه يعتبر unknown بالنسبة للمتصفح،
فالي بنعمله أننا بنعمل script ثاني و نضيفله ال nomodule
و نحط جواه كود يتنفذ في حالة أن المتصفح مش بيدعم ال modules
<script src="..." type="module">
// I will execute only if the browser supports js modules 1️⃣
</script>
<script src="..." nomodule>
// I will execute only if the browser doesn't support modules 2️⃣
</script>
المثال دا هيتنفذ ازاي ؟
لو المتصفح بيدعم ال js modules فكدا ال script رقم 2️⃣ هيتم تجاهله و هيتم تنفيذ الscript رقم 1️⃣
و لو كان المتصفح مش بيدعم ال js modules فكدا ال script رقم 2️⃣ مش هيتنفذ و هيتم تجاهله و هيتم تنفيذ الي script رقم 1️⃣
# | Regular script | Module script | ||
---|---|---|---|---|
Default Mode | Sloppy mode | Strict mode |
- ال regular script : بيكون sloppy mode (default mode) و تقدر برده تخليه strict
- ال module script : بيكون دايما strict mode و بالتالي لو عملت مثلا assign ل undeclared variable هيدي error
<script type="module">
a= 5; // Error
</script>
-
ال Regular Script بيكون global scope بمعني ان لو عندي ملفين js مستدعيهم في ال Html بالشكل ده
<script src="regularScript1.js"></script> <script src="regularScript2.js"></script>
فال
regularScript2
يقدر يستخدم ال functions و ال variables و ال classes ال موجوده فيregularScript1
-
ال module script بيكون ليه scope خاص بيه اسمه
module-level scope
و بالتالي مش هتقدر ت acess علي ال functions و ال variables و ال classes الي جوا ال module دا بطريقة مباشرة زي ما عملنا مع ال regular script
// in moduleScript.js file
let user = "Ali"
// in another js file
alert(user); // Error
هنا أدي error لأن ال user موجود جوا module scope...
طب الحل اي ؟ ازاي نعمل sharing للمحتويات بتاع ال module دا بحيث نقدر نستخدمهم في modules ثانية ؟
الحل هنا أننا هنستخدم special keywords أو special directives معمولين خصيصا عشان نقدر نتعامل مع ال modules و هما ال import
& export
زي كدا :
<!-- index.html -->
<script src="a.js" type="module"></script>
// a.js
let user = "Ali"
export {user}
// b.js
import {user} from "./a.js"
aler(user); // Ali
- ال regular script : ال this بتشير الي ال window object
- ال module script : ال this بتكون undefined و دا لأن ال module زي ما قلنا قبل كدا بيكون strict mode
<!-- in regular scripts -->
<script>
alert(this); // window object
</script>
<!-- in module scripts -->
<script type='module'>
alert(this); // undefined
</script>