フック
はじめに
Cordovaフックは、アプリケーションやプラグイン開発者、あるいは独自のビルドシステムによって追加できる特別なスクリプトであり、Cordovaコマンドをカスタマイズするために使用できます。
Cordovaフックを使用すると、Cordovaコマンドの周囲で特別なアクティビティを実行できます。たとえば、JavaScriptファイルのコードフォーマットをチェックするカスタムツールがあるとします。そして、このツールをビルドごとに実行したいとします。そのような場合、「before_build」フックを使用し、Cordovaランタイムに指示して、ビルドごとにカスタムツールを呼び出すことができます。
フックは、`before_build`、`after_build`など、アプリケーションのアクティビティに関連している場合があります。あるいは、アプリケーションのプラグインに関連している場合があります。たとえば、`before_plugin_add`、`after_plugin_add`などのフックは、プラグイン関連のアクティビティに適用されます。これらのフックは、アプリケーション内のすべてのプラグインに関連付けることも、1つのプラグインのみに関連付けることもできます。
Cordovaは次のフックタイプをサポートしています。
フックタイプ | 関連付けられた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内のプラグインフックは、インストールされるプラグインに対してのみ実行されます。 |
after_plugin_install | ||
before_plugin_uninstall | cordova plugin rm |
プラグインのアンインストール(プラットフォームからの)の前に行われます。plugin.xml内のプラグインフックは、インストールされるプラグインに対してのみ実行されます。 |
フックの定義方法
config.xml
プロジェクトの`config.xml`で`
<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>
プラグインフック (plugin.xml)
プラグイン開発者として、`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`プラグインフックは、インストール/アンインストールされるプラグインに対してのみ実行されます。
フックの実行順序
フックの定義に基づく
特定のフックに対するフックスクリプトは、`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`に関連付けられたフックがあり(プロジェクトに1つのプラグインがインストールされていると仮定)、新しいプラットフォームを追加すると、フックは次の順序で実行されます。
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`に関連付けられたフックがある場合、ビルドコマンドを実行すると、フックは次の順序で実行されます。
before_build
before_prepare
after_prepare
before_compile
after_compile
after_build
スクリプトインターフェース
JavaScript
Node.jsを使用してフックを作成する場合は、次のモジュール定義を使用する必要があります。
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');
Promiseを使用してスクリプトを非同期にすることができます。これは、1秒間待機してから、待機に費やされたミリ秒数を印刷する例です。
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 | 実行されているフックへのパス。 |
CORDOVA_CMDLINE | Cordovaに渡された正確なコマンドライン引数(例:cordova run ios --emulate)。 |
スクリプトがゼロ以外の終了コードを返す場合、親Cordovaコマンドは中止されます。
注記:クロスプラットフォームにするために、Node.jsを使用してフックを作成することを強くお勧めします。上記のJavaScriptセクションを参照してください。
Windows特有の注意点
Windowsで作業していて、フックスクリプトが`*.bat`ファイルでない場合、Cordova CLIはスクリプトの最初の行にシバン行を期待します。これにより、スクリプトの起動に使用するインタープリターがわかります。Pythonスクリプトのシバン行は次のようになります。
#!/usr/bin/env python
使用例
この例では、Cordovaフックを使用して、生成された.apkファイルのサイズをAndroidプラットフォームのコンソール出力にトレースする方法を示します。
空のCordovaアプリを作成し、各プラットフォームのビルド後に`afterBuild.js`スクリプトを実行するようにCordovaに指示する次の定義を`config.xml`に追加します。
<hook type="after_build" src="scripts/afterBuild.js" />
`scripts/afterBuild.js`ファイルを作成し、次の実装を追加します。非同期関数をフックで使用する方法を示すために、`fs.stat`メソッドの非同期バージョンを使用します。
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