Ionicとそれをとりまくエコシステムを整理する

2020/12/25に公開

この記事はIonic Framework / Capacitor Advent Calendar 2020の記事です。やった最終日だー!!


プロダクトなりOSSなりを評価する時に、適切にスコープすることは重要です。しかし、実際には「Ionic使ってアプリストアに公開できるようにする」などとスコープを外して会話しがちで、もちろんコミュニケーション上円滑にまわってるといいのですが、例えば上記の例だと

  • UIコンポーネントをモバイルデザイン(Material Designなど)にあわせてレビューを通す
  • Cordova/CapacitorでNativeビルドとすることで(技術的に)アプリストアに公開できるようにする

の2つの意味を考えることができます。こういうコミュニケーションミスを予防するために、ここでちゃんとIonicとそれをとりまくエコシステムを整理しましょう。

Ionicとそれをとりまくエコシステム

Ionic Framework

@ionic/core

モバイルUIに特化したUIコンポーネントフレームワークです。Web標準規格である Web Components でつくられています。Ionic/Coreは大きくわけて3つのパーツによって構成されています。

DOM Components

HTML上にWeb Componentsを表記するタイプのコンポーネントです。Ionic Frameworkの大部分を占めます。例えば、以下のような表記をします。

<ion-button>Default</ion-button>

API Components

Web ComponentsをJavaScript上で構築して呼び出すタイプのコンポーネントです。以下のような書き方をしますが、やってることは createElement してWeb Componentsを動的に構築しています。

async function presentActionSheet() {
  const actionSheet = document.createElement('ion-action-sheet');
  actionSheet.header = 'Albums';
  actionSheet.buttons = [{
    text: 'Delete',
    handler: () => {
      console.log('Delete clicked');
    }
  }, {
    text: 'Cancel',
  }];
  document.body.appendChild(actionSheet);
  return actionSheet.present();
}

グローバルCSS/CSSユーティリティ

Web Componentsの一番の特徴は、CSSスタイルをDOM内に限定する Shadow DOM なのですが、それとは別にIonic/Coreはグローバルで使えるグローバルCSS/CSSヘルパーを持っています。以下のように使います。

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css"/>
<div class="ion-text-center ion-padding"></div>

@ionic/(JavaScript Framework)

今のところ @ionic/angular , @ionic/react , @ionic/vue がリリースされています。@ionic/core はWeb Componentsなので、JavaScript Frameworkでも直接読み込むことはできますが、以下の2点の問題があります。

  • 型のサポート
  • ルーター

型は何とでもなるのですが、ルーターはJavaScriptフレームワークの作法にのってURL上でステータスを変更しながら、スタックさせたりしようとするとどうしても @ionic/core と一致しない部分がでてきます。なので、 @ionic/core を各フレームワークに最適化し、フレームワークのルーターでモバイルUIを実現するために @ionic/angular , @ionic/react , @ionic/vue がリリースされています。

stencil

Ionic teamが開発している、JSXでWeb Componentsを開発するためのライブラリ。以下のような書き方をします。

import { Component, Prop, h } from '@stencil/core';

@Component({
  tag: 'my-embedded-component'
})
export class MyEmbeddedComponent {
  @Prop() color: string = 'blue';

  render() {
    return (
      <div>My favorite color is {this.color}</div>
    );
  }
}

Ionic Frameworkを開発するためにつくられ、現在も開発が続いています。ドキュメントの自動生成機能もあるというか、stencilはRouter機能やSSG機能もついてるので、これ単独でWebサイトやアプリ開発も可能だったりしますが、本質的にはWeb Componentsを開発するためのライブラリです。

Capacitor

クロスプラットフォーム開発ライブラリでIonic teamが開発しています。Webアセットをソースにして、iOS/AndroidのWebViewアプリをつくることができます。どうやってWebViewがネイティブに呼び出されてるかについて興味がある方は以下の記事をご覧ください。

https://note.com/rdlabo/n/n49c9694fd9d6

ネイティブ機能を使うためには、Capacitorプラグインが公式/OSSで開発されている他、一部を除いてCordovaプラグインも利用することができます。

Capacitor elements

Capacitor3で本格的に導入がはじまる予定のプラットフォームによって自動的に切り替わる共通コンポーネントライブラリです。例えば、カメラだと

  • WebではWeb Componentsで実装されたカメラ機能
  • iOS/AndroidではネイティブAPIからカメラを呼び出す
  • どれもが同一のインターフェイスで利用することができる

となっています。IonicがWeb Components主体であることに対して、Capacitor elementsは、Webを含めたクロスプラットフォームで同一のUIと実装を提供することを目指しています。

Cordova

クロスプラットフォーム開発ライブラリで、Apache財団が開発しています。Capacitorと同様の用途ですが、Capacitorはネイティブコードをユーザが管理することに対して、Cordovaは ビルドする度に自動生成されます。

ですので、ネイティブの知識が不要であるメリットがある反面、「ビルドしたらなぜかエラーがでた」時に対応が難しいといった問題があります。ちなみにCapacitorプラグインは使うことはできません。

Ionic Native

Cordovaは歴史がある(2009年〜)ために、Cordovaプラグインの多くはコールバック関数で実装されており、またTypeScriptでないために、いまどきの開発では不便な場面もあります。

そういった問題点を解決するためにIonic teamが開発しているCordovaプラグインのラッパーが、Ionic Nativeです。Cordovaプラグインと対応するIonic Nativeをインストールすると、Ionic Nativeを通してCordovaプラグインを操作することができます。

おわりに

スコープを整理すると、以下のようなことに気づきます。

  • Ionicとxxライブラリって併用できるの? → ただのWeb Componentsで依存がないためできます
  • Ionic Nativeは不具合が多い! → ただのラッパーなので、Ionic Nativeではなく、Cordovaプラグイン本体のIssueをみにいきましょう
  • RiotでIonicってサポートされてないの? → Web Componentsは利用することができるけど、Riot Routerとの使い分けが難しそう

2020年も終わりですので、知識を整理して2021年を迎えることができましたら幸いです。

それではまた。

Discussion