Hooks
簡介
Cordova Hooks 代表特殊的腳本,可以由應用程式和外掛開發人員,甚至是您自己的建置系統加入,以客製化 cordova 命令。
Cordova hooks 允許您在 cordova 命令周圍執行特殊活動。例如,您可能有一個自訂工具,用於檢查 javascript 檔案中的程式碼格式。而且,您希望在每次建置之前執行此工具。在這種情況下,您可以使用 'before_build' hook,並指示 cordova 執行時在每次建置之前調用自訂工具。
Hooks 可能與您的應用程式活動相關,例如 before_build
、after_build
等。或者,它們可能與您應用程式的外掛相關。例如,諸如 before_plugin_add
、after_plugin_add
等 hooks 適用於外掛相關活動。這些 hooks 可以與您應用程式中的所有外掛相關聯,也可以僅限於一個外掛。
Cordova 支援以下 hook 類型
Hook 類型 | 相關的 Cordova 命令 | 描述 |
---|---|---|
before_platform_add | cordova platform add |
在新增平台之前和之後執行。 |
after_platform_add | ||
before_platform_rm | cordova platform rm |
在移除平台之前和之後執行。 |
after_platform_rm | ||
before_platform_ls | cordova platform ls |
在列出已安裝和可用的平台之前和之後執行。 |
after_platform_ls | ||
before_prepare | cordova prepare cordova platform add cordova build cordova run |
在準備您的應用程式之前和之後執行。 |
after_prepare | ||
before_compile | cordova compile cordova build |
在編譯您的應用程式之前和之後執行。 |
after_compile | ||
before_deploy | cordova emulate cordova run |
在部署您的應用程式之前執行。 |
before_build | cordova build |
在建置您的應用程式之前和之後執行。 |
after_build | ||
before_emulate | cordova emulate |
在模擬您的應用程式之前和之後執行。 |
after_emulate | ||
before_run | cordova run |
在執行您的應用程式之前和之後執行。 |
after_run | ||
before_serve | cordova serve |
在提供您的應用程式之前和之後執行。 |
after_serve | ||
before_clean | cordova clean |
在清除您的應用程式之前和之後執行。 |
after_clean | ||
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_install | cordova plugin add |
在安裝外掛(到平台)之前和之後執行。plugin.xml 中的外掛 hooks 僅針對正在安裝的外掛執行 |
after_plugin_install | ||
before_plugin_uninstall | cordova plugin rm |
在解除安裝外掛(從平台)之前執行。plugin.xml 中的外掛 hooks 僅針對正在安裝的外掛執行 |
定義 hooks 的方法
Config.xml
可以使用 <hook>
元素在專案的 config.xml
中定義 Hooks,例如
<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/android/appAndroidBeforeBuild.bat" />
<hook type="before_build" src="scripts/android/appAndroidBeforeBuild.js" />
<hook type="before_plugin_install" src="scripts/android/appAndroidBeforePluginInstall.js" />
...
</platform>
外掛 hooks (plugin.xml)
作為外掛開發人員,您可以使用 plugin.xml
中的 <hook>
元素定義 hook 腳本,如下所示
<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 執行順序
基於 Hooks 定義
對於給定 hook 的 hook 腳本,會按照它們檔案中的出現順序,依序執行,其中來自 config.xml
的應用程式 hooks 會在來自 plugins/.../plugin.xml
的外掛 hooks 之前執行。
基於內部執行順序
hooks 的內部執行順序是固定的。
範例 1 (cordova platform add)
如果存在與 before_platform_add
、after_platform_add
、before_prepare
、after_prepare
、before_plugin_install
和 after_plugin_install
相關的 hooks(並假設您在專案中安裝了一個外掛),則新增一個新的平台將會按照以下順序執行 hooks
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
相關的 hooks - 執行建置命令將會按照以下順序執行 hooks
before_build
before_prepare
after_prepare
before_compile
after_compile
after_build
腳本介面
Javascript
如果您使用 Node.js 編寫 hooks,則應使用以下模組定義
module.exports = function(context) {
...
}
以下範例展示了 context
物件的內容
{
// The type of hook being run
hook: 'before_plugin_install',
// Absolute path to the hook script that is currently executing
scriptLocation: '/foo/scripts/appBeforePluginInstall.js',
// The CLI command that lead to this hook being executed
cmdLine: 'cordova plugin add plugin-withhooks',
// The options associated with the current operation.
// WARNING: The contents of this object vary among the different
// operations and are currently not documented anywhere.
opts: {
projectRoot: '/foo',
cordova: {
platforms: ['android'],
plugins: ['plugin-withhooks'],
version: '0.21.7-dev'
},
// Information about the plugin currently operated on.
// This object will only be passed to plugin hooks scripts.
plugin: {
id: 'plugin-withhooks',
pluginInfo: { /* ... */ },
platform: 'android',
dir: '/foo/plugins/plugin-withhooks'
}
},
// A reference to Cordova's API
cordova: { /* ... */ }
}
您也可以使用 context.requireCordovaModule
以以下方式在您的腳本中要求額外的 Cordova 模組
const cordovaCommon = context.requireCordovaModule('cordova-common');
您可以使用 Promises 使您的腳本非同步。以下範例僅等待一秒鐘,然後列印等待所花費的毫秒數
module.exports = context => {
return new Promise(resolve => {
const start = Date.now();
setTimeout(() => resolve(Date.now() - start), 1000);
}).then(msWaited => {
console.log(`${context.scriptLocation} waited ${msWaited} ms`);
});
};
非 Javascript
非 javascript 腳本透過 Node child_process spawn 從專案的根目錄執行,並將根目錄作為第一個引數傳遞。所有其他選項都使用環境變數傳遞給腳本
環境變數名稱 | 描述 |
---|---|
CORDOVA_VERSION | Cordova-CLI 的版本。 |
CORDOVA_PLATFORMS | 命令適用的平台之逗號分隔清單(例如:android、ios)。 |
CORDOVA_PLUGINS | 命令適用的外掛 ID 之逗號分隔清單(例如:cordova-plugin-file-transfer、cordova-plugin-file)。 |
CORDOVA_HOOK | 正在執行的 hook 的路徑。 |
CORDOVA_CMDLINE | 傳遞給 cordova 的確切命令列引數(例如:cordova run ios --emulate)。 |
如果腳本傳回非零的結束代碼,則父 cordova 命令將會中止。
注意:我們強烈建議使用 Node.js 編寫您的 hooks,以便它們是跨平台的,請參閱上面的 Javascript 章節。
Windows 特性
如果您在 Windows 上工作,並且您的 hook 腳本不是 *.bat
檔案,Cordova CLI 將會預期 shebang 行作為腳本的第一行。這樣它就知道它需要使用哪個直譯器來啟動腳本。Python 腳本的 shebang 行可能如下所示
#!/usr/bin/env python
範例用法
此範例示範 Cordova hooks 的用法,以追蹤 Android 平台產生的 .apk 檔案大小到主控台輸出。
建立空白的 Cordova 應用程式,並在 config.xml
中新增以下定義,以告知 Cordova 在每次平台建置後執行 afterBuild.js
腳本。
<hook type="after_build" src="scripts/afterBuild.js" />
建立 scripts/afterBuild.js
檔案並新增以下實作。我們使用 fs.stat
方法的非同步版本來示範如何在 hooks 中使用非同步函式。
const fs = require('fs');
const util = require('util');
const stat = util.promisify(fs.stat);
module.exports = function(ctx) {
// Make sure android platform is part of build
if (!ctx.opts.platforms.includes('android')) return;
const platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
const apkFileLocation = path.join(platformRoot, 'build/outputs/apk/android-debug.apk');
return stat(apkFileLocation).then(stats => {
console.log(`Size of ${apkFileLocation} is ${stats.size} bytes`);
});
};
範例中的參數 ctx
由 Cordova 傳遞,並表示執行內容,例如腳本完整路徑、目標平台、命令列引數等,並公開其他輔助功能。有關更多詳細資訊,請參閱上面的 腳本介面
章節。
您現在可以新增 android 平台並執行建置。
cordova platform add android
..
cordova build
..
Size of path\to\app\platforms\android\build\outputs\apk\android-debug.apk is 1821193 bytes