إنشاء مواقع إلكترونية تعمل بشكل جيد على جميع المتصفّحات الرئيسية هو مبدأ أساسي في نظام الويب المفتوح. ومع ذلك، يعني ذلك بذل جهد إضافي للتأكّد من أنّ كل الرموز البرمجية التي تكتبها متوافقة مع كل متصفّح تخطّط لاستهدافه. إذا أردت استخدام ميزات لغة JavaScript الجديدة، عليك تحويل هذه الميزات إلى تنسيقات متوافقة مع المتصفّحات القديمة التي لا تتيحها.
Babel هي الأداة الأكثر استخدامًا لتجميع الرموز البرمجية
التي تحتوي على بنية أحدث في رموز برمجية يمكن أن تفهمها المتصفّحات والبيئات المختلفة
(مثل Node). يفترض هذا الدليل أنّك تستخدم Babel، لذا عليك
اتّباع تعليمات الإعداد لتضمينها في تطبيقك إذا لم يسبق لك ذلك. اختر webpack
في Build Systems إذا كنت تستخدم webpack كمجمِّع الوحدات في تطبيقك.
لاستخدام Babel من أجل الترجمة من مصدر إلى مصدر اللازمة للمستخدمين فقط، عليك تنفيذ ما يلي:
- تحديد المتصفّحات التي تريد استهدافها
- استخدام
@babel/preset-envمع أهداف المتصفّح المناسبة - استخدام
<script type="module">لإيقاف إرسال الرموز البرمجية المحوَّلة إلى المتصفّحات التي لا تحتاج إليها
تحديد المتصفّحات التي تريد استهدافها
قبل البدء في تعديل طريقة تحويل الرموز البرمجية في تطبيقك، عليك تحديد المتصفّحات التي تصل إلى تطبيقك. يمكنك اتّخاذ قرار مستنير من خلال تحليل المتصفّحات التي يستخدمها جمهورك والمتصفّحات التي تخطّط لاستهدافها.
استخدام @babel/preset-env
يؤدي تحويل الرموز البرمجية عادةً إلى إنشاء ملف أكبر من الملف الأصلي. من خلال تقليل مقدار التجميع الذي تجريه، يمكنك تقليل حجم الحِزم لتحسين أداء صفحة الويب.
بدلاً من تضمين مكوّنات إضافية معيّنة لتجميع ميزات لغة معيّنة تستخدمها بشكل انتقائي، توفّر Babel عددًا من الإعدادات المسبقة التي تجمع المكوّنات الإضافية معًا. استخدِم @babel/preset-env لتضمين عمليات التحويل ورموز polyfill اللازمة للمتصفّحات التي تخطّط لاستهدافها فقط.
ضمِّن @babel/preset-env ضمن مصفوفة presets في ملف إعدادات Babel، أي .babelrc:
{
"presets": [
[
"@babel/preset-env",
{
"targets": ">0.25%"
}
]
]
}
استخدِم الحقل targets لتحديد إصدارات المتصفّحات التي تريد تضمينها من خلال إضافة طلب بحث مناسب إلى الحقل browsers. يتكامل @babel/preset-env مع browserslist، وهو إعداد مفتوح المصدر تتم مشاركته بين أدوات مختلفة لاستهداف المتصفّحات. تتوفّر قائمة كاملة بطلبات البحث المتوافقة في الـ
مستندات browserslist.
هناك خيار آخر وهو استخدام ملف .browserslistrc لإدراج البيئات
التي تريد استهدافها.
تطلب القيمة ">0.25%" من Babel تضمين عمليات التحويل
اللازمة لإتاحة استخدام المتصفّحات التي تمثّل أكثر من% 0.25 من الاستخدام العالمي
فقط. يضمن ذلك ألا تحتوي حِزمتك على رموز برمجية محوَّلة غير ضرورية للمتصفّحات التي يستخدمها عدد قليل جدًا من المستخدمين.
في معظم الحالات، يكون هذا النهج أفضل من استخدام الإعدادات التالية:
"targets": "last 2 versions"
تحوّل القيمة "last 2 versions" الرموز البرمجية لـ
آخر إصدارَين من كل متصفّح،
ما يعني توفير الدعم للمتصفّحات المتوقّفة، مثل Internet Explorer.
يمكن أن يؤدي ذلك إلى زيادة حجم حِزمتك بدون داعٍ إذا كنت لا تتوقّع استخدام هذه المتصفّحات للوصول إلى تطبيقك.
في النهاية، عليك اختيار المجموعة المناسبة من طلبات البحث لاستهداف المتصفّحات التي تناسب احتياجاتك فقط.
تفعيل إصلاحات الأخطاء الحديثة
يجمّع @babel/preset-env ميزات بنية JavaScript المتعدّدة في مجموعات، ويُفعِّلها ويُوقِفها استنادًا إلى المتصفّحات المستهدَفة المحدّدة. على الرغم من أنّ هذه الميزة تعمل بشكل جيد، يتم تحويل مجموعة كاملة من ميزات البنية عندما يحتوي متصفّح مستهدَف على خطأ في ميزة واحدة فقط.
غالبًا ما يؤدي ذلك إلى تحويل رموز برمجية أكثر من اللازم.
تم تطوير خيار bugfixes option في @babel/preset-env
في الأصل كـ إعداد مسبق منفصل، ويحلّ هذه المشكلة من خلال تحويل البنية الحديثة التي لا تعمل في بعض المتصفّحات إلى أقرب بنية مكافئة لا تحتوي على أخطاء في هذه المتصفّحات. والنتيجة هي رمز برمجية حديثة متطابقة تقريبًا مع بعض التعديلات الصغيرة في البنية التي تضمن التوافق مع جميع المتصفّحات المستهدَفة. لاستخدام هذا
التحسين، تأكَّد من تثبيت الإصدار 7.10 أو إصدار أحدث من @babel/preset-env، ثم اضبط السمة
bugfixes على true:
{
"presets": [
[
"@babel/preset-env",
{
"bugfixes": true
}
]
]
}
في Babel 8، سيتم تفعيل خيار bugfixes تلقائيًا.
استخدام <script type="module">
وحدات JavaScript، أو وحدات ES، هي ميزة جديدة نسبيًا تتيحها جميع المتصفّحات الرئيسية. يمكنك استخدام الوحدات لإنشاء نصوص برمجية يمكنها استيراد وتصدير البيانات من وحدات أخرى، ولكن يمكنك أيضًا استخدامها مع @babel/preset-env لاستهداف المتصفّحات التي تتيحها فقط.
بدلاً من طلب إصدارات متصفّحات معيّنة أو حصة سوقية، ننصحك بتحديد
"esmodules" : true داخل ملف .babelrc في الحقل targets.
{
"presets":[
[
"@babel/preset-env",
{
"targets":{
"esmodules": true
}
}
]
]
}
تتيح البيئات التي تتيح وحدات JavaScript العديد من ميزات ECMAScript الأحدث التي تم تجميعها باستخدام Babel. من خلال إجراء ذلك، يمكنك تبسيط عملية التأكّد من أنّه يتم استخدام الرموز البرمجية المحوَّلة فقط للمتصفّحات التي تحتاج إليها فعلاً.
تتجاهل المتصفّحات التي تتيح الوحدات النصوص البرمجية التي تحتوي على السمة nomodule.
في المقابل، تتجاهل المتصفّحات التي لا تتيح الوحدات عناصر النصوص البرمجية التي تحتوي على
type="module". هذا يعني أنّه يمكنك تضمين وحدة بالإضافة إلى رمز احتياطي مجمَّع.
في الحالة المثالية، يتم تضمين النصوص البرمجية للإصدارَين من التطبيق على النحو التالي:
<script type="module" src="main.mjs"></script>
<script nomodule src="compiled.js" defer></script>
تجلِب المتصفّحات التي تتيح الوحدات main.mjs وتنفّذه وتتجاهل compiled.js. بينما تفعل المتصفّحات التي لا تتيح الوحدات العكس.
إذا كنت تستخدم webpack، يمكنك ضبط أهداف مختلفة في إعداداتك لإصدارَين منفصلَين من تطبيقك:
- إصدار للمتصفّحات التي تتيح الوحدات فقط
- إصدار يتضمّن نصًا برمجيًا مجمَّعًا يعمل في أي متصفّح قديم يحتوي هذا الإصدار على ملف أكبر، لأنّ عملية التحويل تحتاج إلى إتاحة استخدام مجموعة أوسع من المتصفّحات.
نشكر Connor Clark وJason Miller على مراجعتَيهما.