الخطافات في كوردوفا

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

خُطافات كوردوفا هي نصوصٌ برمجية خاصة يمكن إضافتها من قِبل مطوري التطبيقات والإضافات، أو حتى من طرف نظام البناء (build) الخاص بك لتخصيص أوامر كوردوفا. تسمح لك خطافات كوردوفا بالقيام بأنشطة خاصة ترافق أوامر كوردوفا. على سبيل المثال، قد تكون لديك أداة مخصصة للتحقق من تنسيق التعليمات البرمجية في ملف جافاسكريبت خاصتك. وتود تشغيل هذه الأداة قبل كل عملية بناء. في مثل هذه الحالة، يمكنك استخدام الخطاف 'before_build' وجعل كوردوفا تشغّل هذه الأداة المخصصة وقت التشغيل، بحيث تُستدعى قبل كل عملية بناء.

قد ترتبط الخطافات بأنشطة التطبيق الخاصة بك، كما هو الحال في الخطافين before_build و after_build وغيرهما، أو قد ترتبط بإضافات تطبيقك. على سبيل المثال، ينطبق الخطافان before_plugin_add و after_plugin_add وغيرهما على الأنشطة المتعلقة بالإضافة. يمكن ربط هذه الخطافات بجميع الإضافات داخل التطبيق، أو يمكن أن تكون مخصوصة بإضافة واحدة فقط.

تدعم كوردوفا أنواع الخطافات التالية:

نوع الخطاف أوامر كوردوفا المقابلة الشرح
before_platform_add cordova platform add يُنفّذ هذا الخُطّاف قبل وبعد إضافة المنصة.
before_platform_add
before_platform_rm cordova platform rm يُنفّذ قبل وبعد إزالة المنصة.
after_platform_rm
before_platform_ls cordova platform ls يُنفّذ قبل وبعد إدراج المنصات المثبتة والمتاحة.
after_platform_ls
before_prepare cordova preparecordova platform addcordova buildcordova run ينفّذ قبل وبعد تحضير (preparing) تطبيقك.
after_prepare
before_compile cordova compilecordova build يُنفّذ قبل وبعد تصريف (compiling) نطبيقك.
after_prepare
before_deploy cordova emulatecordova run يُنفّذ قبل نشر التطبيق.
before_build cordova build يُنفّذ قبل وبعد بناء التطبيق.
after_build
before_emulate cordova emulate يُنفّذ قبل وبعد محاكاة التطبيق.
after_emulate
before_run cordova run يُنفّذ قبل وبعد تشغيل التطبيق.
after_run
before_serve cordova serve يُنفّذ قبل وبعد خدمة (serving) التطبيق.
after_serve
before_clean cordova clean يُنفّذ قبل وبعد تنظيف (cleaning) التطبيق.
after_clean
pre_package N/A قابل للتطبيق في Windows 8 و Windows Phone فقط. هذا الخطاف موقوفٌ الآن.
before_plugin_add cordova plugin add يُنفّذ قبل وبعد إضافة الإضافة.
after_plugin_add
before_plugin_rm cordova plugin rm يُنفّذ قبل وبعد إزالة الإضافة.
after_plugin_rm
before_plugin_ls cordova plugin ls يُنفّذ قبل وبعد عرض قائمة تضم الإضافات الموجودة في تطبيقك.
after_plugin_ls
before_plugin_search cordova plugin search يُنفّذ قبل وبعد البحث عن الإضافة.
after_plugin_search
before_plugin_install cordova plugin add يُنفّذ قبل وبعد تثبيت الإضافة (على المنصات). يتم تنفيذ خطافات الإضافات في plugin.xml عند إضافة الإضافات فقط.
after_plugin_install
before_plugin_uninstall cordova plugin rm يُنفّذ قبل إلغاء تثبيت الإضافة (من المنصات). يتم تنفيذ خطافات الإضافات في plugin.xml عند تثبيت إضافة فقط.

طرق تعريف الخطافات

Config.xml

يمكن تعريف الخطافات في الملف config.xml الخاص بالمشروع باستخدام الوسم <hook>.

إليك المثال التالي:

<hook type="before_build" src="scripts/appBeforeBuild.bat" />
<hook type="before_build" src="scripts/appBeforeBuild.js" />
<hook type="before_plugin_install" src="scripts/appBeforePluginInstall.js" />
<platform name="android">
    <hook type="before_build" src="scripts/wp8/appAndroidBeforeBuild.bat" />
    <hook type="before_build" src="scripts/wp8/appAndroidBeforeBuild.js" />
    <hook type="before_plugin_install" src="scripts/wp8/appWP8BeforePluginInstall.js" />
    ...
</platform>
<platform name="windows">
    <hook type="before_build" src="scripts/windows/appWinBeforeBuild.bat" />
    <hook type="before_build" src="scripts/windows/appWinBeforeBuild.js" />
    <hook type="before_plugin_install" src="scripts/windows/appWinBeforePluginInstall.js" />
    ...
</platform>

خطافات الإضافات (plugin.xml)

كمطور للإضافات، يمكنك تعريف برامج الخطافات النصية باستخدام الوسم <hook> في الملف plugin.xml على النحو التالي:

<hook type="before_plugin_install" src="scripts/beforeInstall.js" />
<hook type="after_build" src="scripts/afterBuild.js" />
<platform name="android">
    <hook type="before_plugin_install" src="scripts/androidBeforeInstall.js" />
    <hook type="before_build" src="scripts/androidBeforeBuild.js" />
    ...
</platform>

سيتم تفعيل خطافات الإضافات before_plugin_install و after_plugin_install و before_plugin_uninstall حصريًا عند تثبيت أو إلغاء تثبيت الإضافات.

عبر المجلد ‎/hooks (مُتجاوز)

لتنفيذ إجراء مخصص عند إطلاق نوع الخطاف المقابل، استخدم نوع الخطاف كاسم لمجلد فرعي داخل المجلد 'hooks'، وضع ملف البرنامج النصي هناك، كما هو موضح في المثال التالي:

# script file will be automatically executed after each build
hooks/after_build/after_build_custom_action.js

عند استخدام هذه الخطافات، سيتم تشغيلها كملفات قابلة للتنفيذ (executable)، وليس كوحدات جافاسكريبت قابلة للتحميل.

تذكر أن تجعل برنامجك النصي قابلًا للتنفيذ في هذه الحالة.

ملاحظة: هذه الطريقة صارت مُتجاوزة، استخدم بدلًا منها الوسم hook في الملفين config.xml و plugin.xml.

ترتيب تنفيذ الخطافات

بناء على تعريف الخطاف

يمكن تعريف النصوص البرمجية للخطافات عن طريق إضافتها إلى المجلد المحدد مسبقًا (‎/hooks)، أو عبر ملفات الإعداد (config.xml و plugin.xml)، بحيث تُشغّل وفق الترتيب التالي:

  • خطافات التطبيق الموجودة في المجلد‎/hook ؛
  • خطافات التطبيق من الملف config.xml؛
  • خطافات الإضافات من الملف plugins/.../plugin.xml.

بناءً على الترتيب الداخلي للتنفيذ

الترتيب الداخلي لتنفيذ الخطافات ثابت.

مثال 1 (إcordova platform add)

إن كانت هناك خطافات مرتبطة بـ before_platform_add و after_platform_add و before_prepare و after_prepare و before_plugin_install و after_plugin_install (وعلى افتراض أن لديك إضافةً واحدة مثبتة في مشروعك)، فإن إضافة منصة جديدة سيُؤدي إلى تنفيذ الخطافات وفق الترتيب التالي:

before_platform_add
    before_prepare
    after_prepare
    before_plugin_install
    after_plugin_install
after_platform_add

المثال 2 (cordova build)

إن كانت هناك خطافات مرتبطة بـ before_prepare و after_prepare و before_compile و after_compile و before_build و after_build - فسيؤدي تشغيل الأمر build إلى تنفيذ الخطافات وفق الترتيب التالي:

before_build
    before_prepare
    after_prepare
    before_compile
    after_compile
after_build

واجهة البرنامج النصي (Script Interface)

ملاحظات خاصة بمنصة ويندوز

إن كنت تعمل على ويندوز، وفي حال لم يكن ملف برنامجك النصي (جافاسكريبت أو غيره) من النوع bat (وهو أمر موصى به، إن كنت تريد أن يعمل برنامجك النصي في أنظمة تشغيل أخرى غير ويندوز)، فإن واجهة سطر الأوامر ستتوقع وجود سطر shebang (سطر يبدأ بالسلسلة النصية "‎#!‎") كسطر أول لتعرف المترجم (interpreter) الذي يجب استخدامه لتشغيل البرنامج النصي. يجب أن يطابق سطر shebang الصيغة التالية:

#!/usr/bin/env [name_of_interpreter_executable]‎

جافاسكريبت

إن كنت تكتب الخطافات باستخدام Node.js، فيجب عليك استخدام تعريف الوحدة التالي:

module.exports = function(context) {
    ...
}

يحتوي الكائن context على نوع الخطاف، والمسار الكامل للنص البرمجي المُنفّذ، وخيارات الخُطاف، ووسائط واجهة سطر الأوامر المُمررة إلى كوردوفا، وكائن كوردوفا من المستوى الأعلى (top-level) وفق التنسيق التالي:

{
  "hook": "before_plugin_install",
  "scriptLocation": "c:\\script\\full\\path\\appBeforePluginInstall.js",
  "cmdLine": "The\\exact\\command\\cordova\\run\\with arguments",
  "opts": {
    "projectRoot":"C:\\path\\to\\the\\project",
    "cordova": {
      "platforms": ["android"],
      "plugins": ["plugin-withhooks"],
      "version": "0.21.7-dev"
    },
    "plugin": {
      "id": "plugin-withhooks",
      "pluginInfo": {
        ...
      },
      "platform": "android",
      "dir": "C:\\path\\to\\the\\project\\plugins\\plugin-withhooks"
    }
  },
  "cordova": {...}
}

لن يُمّرّر الكائن context.opts.plugin إلا إلى البرامج النصية الخاصة بخطافات الإضافات.

يمكنك أيضًا استيراد (require) وحدات كوردوفا إضافية في برنامجك النصي باستخدام context.requireCordovaModule بالطريقة التالية:

var Q = context.requireCordovaModule('q');

يمكنك جعل برامجك النصية متزامنة باستخدام المتغير Q:

module.exports = function(context) {
    var Q = context.requireCordovaModule('q');
    var deferral = new Q.defer();
    setTimeout(function(){
      console.log('hook.js>> end');
    deferral.resolve();
    }, 1000);
    return deferral.promise;
}

ملاحظة: لا تَُستخدم واجهة البرنامج النصي لمٌحمِّل الوحدة (module loader) إلا مع ملفات ‎.js المعرّفة من طرف الملفين config.xml و plugin.xml.

لأغراض التوافق، يتم تشغيل ملفات الخطاف المحددة بواسطة المجلد ‎/hooks عبر الأمر Node child_process spawn، راجع قسم "دون جافاسكريبت" أدناه.

دون جافاسكريبت

يتم تشغيل البرامج النصية التي لا تستخدم جافاسكريبت (Non-javascript scripts) عبر الأمر Node child_process spawn من المجلد الجذري للمشروع، مع تمرير المجلد الجذري كوسيط أول. وتُمرر جميع الخيارات الأخرى إلى البرنامج النصي باستخدام متغيرات البيئة:

اسم متغير البيئة الشرح
CORDOVA_VERSION إصدار Cordova-CLI.
CORDOVA_PLATFORMS قائمة مفصولة بفواصل تحتوي المنصات التي ينطبق عليها الأمر (على سبيل المثال: android أو ios).
CORDOVA_PLUGINS قائمة مفصولة بفواصل لمُعرفات (IDs) الإضافات التي ينطبق عليها الأمر (على سبيل المثال: cordova-plugin-file-transfer و cordova-plugin-file).
CORDOVA_HOOK مسار الخُطاف الذي يتم تنفيذه.
CORDOVA_CMDLINE وسائط واجهة سطر الأوامر المُمررة إلى كوردوفا (على سبيل المثال: cordova run ios --emulate).

إن أعاد البرنامج النصي قيمة مخالفة للصفر، فسيتم إنهاء الأمر الأب (parent command) لكوردوفا.

ملاحظة: نوصي بشدة بأن تكتب خطافاتك باستخدام Node.js، حتى تكون عابرةً للمنصات (cross-platform)، انظر القسم جافاسكريبت أعلاه لمزيد من التفاصيل.

مثال

يوضح هذا المثال كيفية استخدام خطافات كوردوفا لطباعة حجم الملف المُنشأ ‎.apk لمنصة أندرويد في مخرجات وحدة التحكم (console).

قم بإنشاء تطبيقٍ فارغ، وأضف التعريف التالي إلى الملف config.xml لإعلام كوردوفا بتشغيل البرنامج النصي afterBuild.js بعد كل عملية بناء للمنصة.

<hook type="after_build" src="scripts/afterBuild.js" />

أنشئ الملف scripts/afterBuild.js، وأضف إليه المحتويات التالية. سنستخدم إصدارًا متزامنًا للتابع fs.stat لشرح كيفية استخدام ميزة التزامن بواسطة الخطافات.

module.exports = function(ctx) {
    // تأكد من أن أندرويد جزء من البناء
    if (ctx.opts.platforms.indexOf('android') < 0) {
        return;
    }
    var fs = ctx.requireCordovaModule('fs'),
        path = ctx.requireCordovaModule('path'),
        deferral = ctx.requireCordovaModule('q').defer();
    var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
    var apkFileLocation = path.join(platformRoot, 'build/outputs/apk/android-debug.apk');
    fs.stat(apkFileLocation, function(err,stats) {
        if (err) {
                deferral.reject('Operation failed');
        } else {
            console.log('Size of ' + apkFileLocation + ' is ' + stats.size +' bytes');
            deferral.resolve();
        }
    });
    return deferral.promise;
};

يُمرّر المعامل ctx في المثال أعلاه من طرف كوردوفا، حيث يعطي معلومات عن سياق التنفيذ، مثل المسار الكامل للبرنامج النصي، والمنصة المستهدفة، ووسائط واجهة سطر الأوامر، وما إلى ذلك، ويعرض أيضًا وظائف إضافية للمساعدة. انظر القسم واجهة البرنامج النصي أعلاه لمزيد من التفاصيل.

يمكنك الآن إضافة نظام أندرويد وتنفيذ عملية البناء.

cordova platform add android
..
cordova build
..
Size of path\to\app\platforms\android\build\outputs\apk\android-debug.apk is 1821193 bytes‎

يمكن العثور على المزيد من الأمثلة المفيدة في هذا المقال: ثلاث خطافات تحتاجها تطبيقات Phone Gap.

انظر أيضا

مصادر