ترجمة الأصول (Laravel Mix)

من موسوعة حسوب

مقدمة

يوفّر Laravel Mix واجهة برمجية (API) واضحة لتعريف خطوات بناء Webpack للتطبيق باستعمال العديد من المعالجات المسبقة (pre-processors) للغتي CSS و Javascript. باستخدام سلسلة بسيطة من استدعاءات التوابع، يمكن تعريف مسار معالجة الأصول (assets) في التطبيق. فمثلًا:

mix.js('resources/assets/js/app.js', 'public/js')

  .sass('resources/assets/sass/app.scss', 'public/css');

إن أصبحت مرتبكا و مشوشا حول البدء مع Webpack وترجمة الأصول، فسوف تحب Laravel Mix. لكنك لست مطالبًا باستعمالها لبناء تطبيقك. طبعًا لك حرية اختيار أي مسار لمعالجة الأصول تريده، أو أن لا تستعمل أيًا منها على الإطلاق.

التثبيت والتجهيز

تثبيت Node

قبل البدء باستخدام Mix، يجب أولًا التأكد من أنّ Node.js و npm مثبّتة بطريقة صحيحة

node -v 
npm -v

في العادة، يتضمّن Laravel Homestead كل ما تحتاج له. لكن إن لم تكن تستعمل Vagrant، فيمكنك استعمال آخر إصدارات Node.js و npm بسهولة من صفحة تنزيلها.

Laravel Mix

الخطوة الوحيدة المتبقية هي تثبيت Laravel Mix. في تطبيق Laravel جديدة، ستجد الملف package.json في الملف الرئيسي للتطبيق. يتضمن الملف package.json كل ما تحتاج له للبداية. يمكنك أن تعدّه مثل composer.json لكن لاعتماديات Node بدل PHP. يمكنك تثبيت الاعتماديات المذكورة في هذا الملف عبر الأمر:

npm install

تشغيل Mix

Mix هي طبقة ضبط فوق Webpack .لتشغيل مهمّات Mix، يجب فقط تنفيذ أحد سكربتات npm الموجودة في الملف package.json:

// تشغيل المهام

npm run dev

// تشغيل المهام وتصغير المخرجات

npm run production

مراقبة تغيرات الأصول

سيواصل الأمر npm run watch العمل في الطرفية ويراقب كل تغيّر في الملفات. سيعيد Webpack تلقائيًا ترجمة الأصول كّلما طرأ تغيير:

npm run watch

قد تلاحظ أن Webpack لا يقوم بالتحديث في بعض البيئات عند تغيّر الملفات. في هذه الحالة يمكن استعمال الأمر:

npm run watch-poll

التعامل مع صفحات الأنماط

الملف webpack.mix.js هو نقطة البداية لترجمة الأصول. يمكنك عدّه طبقةَ ضبطٍ بسيطةً حول Webpack. يمكن سَلسلة (chain) مهمّات Mix معًا لتحديد كيفية ترجمة الأصول بدقّة.

Less

يمكن استعمال التابع Less لترجمة Less إلى CSS. لنترجم الملف الأولي app.less إلى الملف public/css/app.css:

mix.less('resources/assets/less/app.less', 'public/css');

تُستعمل النداءات المتكرّرة للتابع Less لترجمة أكثر من ملف واحد:

mix.less('resources/assets/less/app.less', 'public/css')

  .less('resources/assets/less/admin.less', 'public/css');

لتجاوز ضبط Less المبدئي، فيمكنك تمرير معامل ثالث للتابع ()mix.less:

mix.less('resources/assets/less/app.less', 'public/css', {

   strictMath: true

});

Sass

يسمح التابع Sass بترجمة Sass إلى CSS. يمكن استعمال التابع كالآتي:

mix.sass('resources/assets/sass/app.scss', 'public/css');

كما بالنسبة للتابع Less، يمكن استعمال النداءات المتعددة لترجمة ملفات Sass عديدة دفعة واحدة لملفات CSS وتغيير مكان الملفات الناتجة

mix.sass('resources/assets/sass/app.sass', 'public/css')

  .sass('resources/assets/sass/admin.sass', 'public/css/admin');

Stylus

بطريقة مشابهة لنظيراتها Less و Sass، تسمح الدالة Stylus بترجمة ٍStylus إلى CSS:

mix.stylus('resources/assets/stylus/app.styl', 'public/css');

يمكن أيضا تثبيت إضافات Stylus مثل Rupture. أولا ثبت الإضافة عبر npm:

npm install rupture

ثمّ ضمِّن الإضافة باستعمال ()mix.stylus:

mix.stylus('resources/assets/stylus/app.styl', 'public/css', {

   use: [
       require('rupture')()
   ]

});

PostCSS

PostCSS هي أداة قوية لتحويل CSS، وهي مضَمّنَة في Laravel Mix. في العادة، يستعمل Mix الإضافة Autoprefixer ليعطي تلقائيًا السابقات الضرورية لخاصيات CSS3. لكن لك الحرية لاختيار أي إضافات يحتاج لها التطبيق. ثبت أولًا الإضافة عبر npm ثمّ أشر إليها في الملف webpack.mix.js

mix.sass('resources/assets/sass/app.scss', 'public/css')

  .options({
       postCss: [
           require('postcss-css-variables')()
       ]
  });

شيفرات CSS العادية

إن أردت دمج عدّة ملفات CSS عادية في ملف واحد، فيمكنك استعمال التابع style:

mix.styles([

   'public/css/vendor/normalize.css',
   'public/css/vendor/videojs.css'

], 'public/css/all.css');

معالجة مسارات العناوين URL

لأن Laravel Mix مبني فوق Webpack، من المهم فهم بعض مفاهيم Webpack. بالنسبة لترجمة CSS، سيعيد Webpack كتابة وتحسين أي نداء لعنوان ()url في النمط. في حين قد يبدو هذا غريبًا، إلّا أنها خاصية قوية ومفيدة. تخيّل أنك تريد ترجمة Sass يحتوي مسارًا نسبيًا لصورة:

example {

   background: url('../images/example.png');

}

لن تتم إعادة كتابة المسارات المطلقة. مثلا url('/images/thing.png')‎ و url('http://example.com/images/thing.png')‎ لن تتم إعادة كتابتها.

افتراضيا، سيجد كل من Laravel Mix و Webpack الملف example.png، يصنعان نسخة في مجلد public/images، ثمّ يعيدان كتابة ()url في صفحة الأنماط الناتجة. فتبدو شيفرة CSS المترجَمة كالآتي:

example {

 background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);

}

على الرغم من أن هذه الخاصية مفيدة جدا، في بعض الأحيان تكون ٌقد ضبطت هيكلة الملفات بالطريقة التي تريد و ترغب في تعطيل إعادة كتابة عناوين url()‎:

mix.sass('resources/assets/app/app.scss', 'public/css')

  .options({
     processCssUrls: false
  });

بإضافة هذا إلى webpack.mix.js، سيتوقّف Mix عن إعادة كتابة العناوين أو نسخ الأصول إلى الملف public. يعني أنّ شيفرة CSS المترجمة ستكون كما كتبته في البداية:

example {

   background: url("../images/thing.png");

}

خرائط المصادر (Source Maps)

بالرغم من أنّها معطّلة عند البداية، إلّا أن خرائط المصادر يمكن أن تَشغّل عبر نداء التابع mix.sourceMaps()‎ في webpack.mix.js. وبالرغم من التكلفة العالية على الترجمة وعلى الأداء في التطبيق، إلّا أنّها توفّر معلومات إضافية للتنقيح في أدوات المطور في المتصفح عند ترجمة الأصول:

mix.js('resources/assets/js/app.js', 'public/js')

  .sourceMaps();

التعامل مع شيفرات JavaScript

وفّر Mix العديد من الخصائص للمساعدة للتعامل مع شيفرات JavaScript، مثل ترجمة ECMAScript 2015، وتجميع الوحدات، والتصغير، ودمج ملفات JavaScript العادية. و كل هذا يعمل دون الحاجة لإعادة ضبط أي شيء:

mix.js('resources/assets/js/app.js', 'public/js');

بهذا السطر الوحيد تحصل على الميزات التالية:

  • نصوص ES2015
  • الوحدات
  • ترجمة ملفات ‎
  • vue
  • التصغير (minification) للبيئات الإنتاجية

استخراج Vendor

الشيء السيء الوحيد الذي يمكن أن يحصل من تجميع شيفرات JavaScript الخاصة بالتطبيق مع المكتبات هي إن كنت تنوي تحديث شيفرة JavaScript باستمرار، يجب أن تفكر في استخراج مكتبات Vendor التي يوفّرها Vendor هي جعل التخزين المؤقت لفترات طويلة أكثر صعوبة. مثلا، أي تحديث لكود التطبيق سيجبر المتصفح على إعادة تحميل كل مكتبات Vendor حتى إن لم تُغيَّر.

إن كنت تنوي إدخال تحديثات كثيرة لشيفرة JavaScript من التطبيق، فيجب أن تُفكر في استخراج مكتبات Vendor في ملفات خاصة لها. بهذه الطريقة، تغيير كود التطبيق لن يؤثر على ملف vendor.js الكبير. التابع extract يُستعمل لتسهيل ذلك:

mix.js('resources/assets/js/app.js', 'public/js')

  .extract(['vue'])

التابع extract يقبل مصفوفة من المكتبات أو الوحدات التي تريد استخراجها في الملف vendor.js. باستعمال الشيفرة أعلاه، يصنع التطبيق الملفات التالية:

  • public/js/manifest.js : بيئة تشغيل Webpack
  • public/js/vendor.js : مكتبات Vendor
  • public/js/app.js : شيفرة التطبيق

لتفادي الأخطاء في JavaScript، تأكد من تحميل الملفات بالترتيب الصحيح

<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>

React

يمكن ل Mix أن يثبت إضافات Babel الضرورية لتشغيل React. وذلك بتعويض mix.js()‎ إلى mix.react()‎

mix.react('resources/assets/js/app.jsx', 'public/js');

خلف الستار، سيُنزّل Mix الإضافة الضرورية babel-preset-react.

شيفرة JavaScript الخام (Vanilla JS)

مثلما يمكنك دمج عدة أنماط ب ()mix.styles، يمكنك أيضا دمج و تصغير عدة سكربتات JavaScript باستعمال الدالة scripts()‎:

mix.scripts([

   'public/js/admin.js',
   'public/js/dashboard.js'

], 'public/js/all.js');

هذا الخيار مفيد خاصة في التطبيقات القديمة التي لا تحتاج لترجمة Webpack لشيفرات JavaScript.

ملاحظة: تغيير بسيط عن mix.scripts()‎ هو mix.babel()‎. هذا التابع يعمل بطريقة مشابهة للتابع scripts لكن الملف سيحمل ترجمة Babel التي تحول أي شيفرة ES2015 إلى شيفرة JavaScript عادية تفهمها كل المتصفحات.

ضبط Webpack خاص

افتراضيا، يستعمل Laravel Mix ملف الضبط المسبق webpack.config.js لبدء العمل دون تأخير. قد تحتاج لإعادة الضبط يدويًا في بعض الأحيان. قد يكون لديك محمّل خاص أو إضافة يجب أن تذكر أو قد تريد استعمال stylus بدل Sass. في هذه الحالة لديك خياران:

دمج ضبوطات خاصة

يوفّر Mix تابعًا مفيدًا لهذا هو webpackConfig الذي يسمح بدمج أي ضبط Webpack إضافي. قد يكون هذا الخيار جذّابًا إذ لا يتطلب إعادة كتابة الملف webpack.config.js. يقبل التابع webpackConfig كائنًا (object) على أن يتضمن ضبط Webpack خاص الذي تريد تنفيذه.

mix.webpackConfig({

   resolve: {
       modules: [
           path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
       ]
   }

});

ملفات ضبط خاصة

إن أردت تخصيصًا كليًا لملف الضبط، انقل نسخة من الملف node_modules/laravel-mix/setup/webpack.config.js للمجلد الجذر للتطبيق، ثمّ وجّه كل الإشارات إلى config-- في package.json نحو الملف المنسوخ حديثا. إن اخترت هذه الطريقة في الضبط، كل التحديثات اللاحقة للملف webpack.config.js يجب أن تنقل يدويا للملف الجديد

نسخ الملفات والمجلّدات

يُستخدم التابع copy لنسخ ملف أو مجلّد إلى مكان جديد. يكون هذا مفيدًا حين تحتاج إحدى الأصول من المجلّد node_modules لأن تُنقل نحو المجلد public.

mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');

حين نقل مجلد ستضر الدالة copy بمحتواه (إذ ستُسطِّح بنية المجلد) لذا يُفضّل استخدام التابع copyDirectory عوضًا عنها:

mix.copyDirectory('assets/img', 'public/img');

أرقام الإصدارات والذاكرة التخزينية المؤقتة

يضيف بعض المبرمجين إلى الأصول المترجمة بصمةً زمنيةً أو رقمًا خاصًّا لإرغام المتصفح على تحميل الملف الجديد بدلا عن نسخ قديمة. يتعامل Mix مع هذا باستعمال التابع version.

يضيف التابع version تلقائيّا رقمًا خاصًا لكل أسماء الملفات المترجمة. ممّا يسمح باستخدام أكثر راحة لذاكرة التخزين المؤقتة.

mix.js('resources/assets/js/app.js', 'public/js')

  .version();

بعد إنشاء الإصدار الجديد للملف، لن تعرف الاسم الدقيق للملف لذا يجب عليك أن تستعمل الدالة mix في واجهتك لتحميل الأصل الصحيح. تعرف الدالة mix تلقائيّا الاسم الصحيح ورقم الإصدار للأصل المطلوب:

<link rel="stylesheet" href="{{ mix('/css/app.css') }}">

لأن الملفات المرفقة برقم إصدار في العادة غير مفيدة في بيئة التطوير، يمكن أن تقوم بتعيين الإصدارات فقط في بيئة الإنتاج npm run production

mix.js('resources/assets/js/app.js', 'public/js');

if (mix.inProduction()) {

   mix.version();

}

إعادة التحميل Browsersync

يستطيع browsersync مراقبة تغيّر الملفات تلقائيّا، ثمّ يضيف التغييرات للمتصفح دون الحاجة لإعادة تحميل المتصفح يدويًا. يمكن تفعيل هذه الخاصّية بنداء التابع mix.browsersync()‎:

mix.browserSync('my-domain.test');

// أو
// https://browsersync.io/docs/options mix.browserSync(){

   proxy: 'my-domain.test'

});

يمكن تمرير إمّا سلسلة نصية (proxy) أو كائن (إعدادات browsersync) للتابع ثمّ تشغيل خادم تطوير webpack عبر الأمر npm run watch. الآن عند تغيير سكربت أو ملف PHP راقب إذ سيعيد المتصفح التحميل وحده ليعكس التغيرات الحاصلة.

متغيرات البيئة

يمكنك إضافة متغيّرات للبيئة بإضافة البادئة _MIX إلى الملف:

MIX_SENTRY_DSN_PUBLIC=http://example.com

بعد تعريف المتغيّر في الملف env.، يمكنك استعماله عبر الكائن process.env. إذا تغيّرت قيمته أثناء تشغيل المهمة watch فيجب إعادة بدء المهمة:

process.env.MIX_SENTRY_DSN_PUBLIC

الإشعارات

عندما تكون متاحة، ستقوم Mix بعرض إشعارات نظام التشغيل ممّا يعطي معلومات آنية على إن تمت الترجمة بنجاح أم لا. لكن قد تكون هناك حالات لا تريد فيها هذه المعلومات كأن لا تريد تفعيل Mix في خادم إنتاجي، في هذه الحالات يمكنك تعطيل الإشعارات عبر التابع disableNotifications:

mix.disableNotifications();

مصادر