三連休初日に、日本中で1人ぐらいにニーズがあるかもしれない記事を書こうと思いたち、せっかくIonic CLIのコントリビューションしてるので(ionic-team/ionic-cli Contributors)、Ionic CLIのコードの簡単な解説をしてみます。
$ npm i -g ionic
でインストールして、それ以降、ionic
コマンドを使えるあいつです。Ionic Teamはソースコードを
で公開しており、CLIの中身をここで確認することができます。
Ionic CLIを手元でコンパイルする
GitHubからcloneしたファイルを使って、Ionic CLIを動かすことができます。試してみる場合は、以下の手順を実行してください。
- https://github.com/ionic-team/ionic-cli をローカルにcloneする
-
npm i
で依存パッケージをインストール -
npm run bootstrap
で、packages/
以下のモノレポ毎の依存パッケージをインストールして、それぞれをリンクさせる -
npm run link
で、グローバルにパスを通します
これで、あなたのionic
コマンドは、cloneしたパッケージから実行されるようになりました。ちなみに、ソースコードの変更を行う時は npm run watch
を実行すると即時反映されます(参考)
CLIの中身
では、CLIの中身についてみていきましょう。
ionic start
ionic start --type=angular
というコマンドを例に、簡単に処理を追っていきます。
このコマンドが実行されると、 packages/ionic/src/commands/start.ts
が呼び出されます。オプションである--type=angular
についてはL96-L100で定義されています。
{
name: 'type',
summary: `Type of project to start (e.g. ${lodash.uniq(starterTemplates.map(t => t.type)).map(type => chalk.green(type)).join(', ')})`,
type: String,
},
ちなみに、ここを削除したら、type
オプションが使えなくなります。オプションを増やす時は、まずここにオプションを定義します。
処理をおおざっぱに説明します。まず、type
オプションがある場合はその文字列を、ない場合はデフォルト値としてionic-angular
が変数projectType
に代入され、this.validateProjectType
で、「入力された文字列が正しいか」の検証を受けます。L202-203行目です。
const projectType = options['type'] ? String(options['type']) : 'ionic-angular'; await this.validateProjectType(projectType);
現在Ionicのtypeは、Ionic v1を意味する ionic1
、 Ionic v2-3の ionic-angular
、 Ionic v4の angular
の3通りがあり、それ以外はエラーがでます。ここで、CLIではじめるIonicのバージョンを決定しています。
次に、プロジェクト名とスターターテンプレートについて入力済みかどうかの判定があったあと(入力がなかった場合は、入力を求める)、ファイルの生成を行います。L403-408です。
if (this.schema.cloned) {
await this.env.shell.run('git', ['clone', this.schema.url, projectDir, '--progress'], { stdio: 'inherit' });
} else {
const starterTemplate = await this.findStarterTemplate(this.schema.template, this.schema.type, tag);
await this.downloadStarterTemplate(projectDir, starterTemplate);
}
スターターテンプレートがURL指定だった場合は、そこをgit clone
することを試みます。文字列の場合は、公式のstertar templateで存在確認をしたあと、git clone
します。
ですので
$ ionic start projectName https://github.com/rdlabo/ionic-wpcom
とか入力すると、ネット上で公開されているパッケージを使ってそのままionic start
することができるわけです。ハンズオンに役立つ豆知識です。
ionic serveをみてみる
続いて、ionic serve
についてです。
実行されると、[packages/ionic/src/commands/serve.ts]
(https://github.com/ionic-team/ionic-cli/blob/develop/packages/ionic/src/commands/serve.ts)が呼び出されるのですが、ここに記述されている処理はあまりなく、`packages/@ionic/cli-utils/src/lib/serve.ts`にある`serve`メソッドを呼び出しています。
async run(inputs: CommandLineInputs, options: CommandLineOptions): Promise<void> {
if (!this.project) {
throw new FatalException(`Cannot run ${chalk.green('ionic serve')} outside a project directory.`);
}
// TODO: use runner directly
await serve({ flags: this.env.flags, config: this.env.config, log: this.env.log, prompt: this.env.prompt, shell: this.env.shell, project: this.project }, inputs, options);
await sleepForever();
}
このserve
メソッドに受け渡されているproject: this.project
が重要で、これはpackages/@ionic/cli-utils/src/index.ts
のgetProject
メソッドで取得してきている「そのプロジェクトのIonicのバージョン」が格納されています。
projectFile = await readJsonFile(projectFilePath);
具体的には、プロジェクト直下のionic.config.json
の
{
"type": "ionic-angular"
}
の値を見に行っています。
そして、そのIonicのバージョンに従って、@ionic/cli-utils/src/lib/project/
以下のファイルを呼び出して実行します。
例えば、Ionic v3(=ionic-angular
)を使っている場合はpackages/@ionic/cli-utils/src/lib/project/ionic-angular/serve.ts
が呼び出されますし、v4(=angular
)を使っている場合はpackages/@ionic/cli-utils/src/lib/project/angular/serve.ts
が呼び出されます。
内部サーバ立ち上げたり、IPアドレスで起動確認したりあたりはソースコード読んでいただけますと幸いです。
パッケージの簡単な説明
packages/@ionic/
をみると、様々なパッケージがあって混乱すると思うので、私がさわったことあるパッケージのみですが、軽く解説しておきます。
パッケージ名 | 概要 |
---|---|
cli-framework | CLIフレームワークです。ヘルプを呼び出すとか、ログに色つけるとか、そういうCLIっぽいメイン処理をします。 |
cli-utils | CLIのコマンド毎のライブラリ、ヘルパーみたいなもの。Ionicのバージョンによって異なる処理を行う場合はここにメイン処理を書く感じになる。 |
discover | さわったことないです |
lab |
ionic serve --lab でIonic Labを立ち上げる時に使う処理が書いてある。どういう機能かは「ionic serve --lab」で、エミュレーターっぽく動かす参照。 |
ng-toolkit | Ionic v4では、Angular CLIをラップしてIonic CLIを動かすために必要なファイル群。「Angular CLIでビルドしたあとに、Cordova CLIを実行する」みたいな処理が書かれてたはず。 |
schematics-angular | Ionic v4で、ionic g コマンドを実行するためのもの。ng g コマンドをラップするのに必要なファイル。 |
utils-fs |
fs のラッパー。TypeScriptで書きやすく、かつちゃんとPromiseで返してくれるようになってます。voidやcallbackはもうやめよう。 |
utils-network |
ionic serve の時のPortまわりとか。DevAppsの疎通とか。 |
v1-toolkit | Ionic v1まわり |
まとめ
駆け足でしたが、Ionic CLIの中身に興味をもつきっかけになりましたら幸いです。それでは、また。