2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ionic3でアプリを作る際のLazy Loadingへの対応

Posted at

最近(2018年10月)、Ionic3でAndroidアプリを作って、Play Storeで公開しました。

そこに至るにはいろいろと罠がありましたので、その記録を思い出せるうちに書いて残しておこうと思います。

困ったり解決したりする度にツイートしてたからいけるはず……!!

いくつかの記事にわけて、シリーズとしてまとめておきます。

なお、なんとかリリースできたアプリはこちら。あなたの日本語入力速度を測定します。→フリックとローマジ 〜日本語入力スピード測定〜

#シリーズ一覧

この記事では、Lazy Loadingについて扱いますが、PageとComponentの場合の話だけします。PipeやDirectiveの場合については触れませんが、基本的にComponentの場合と同じです。

#Lazy Loading????

Lazy Loadingとは、アプリ内で使うモジュールを、必要な分だけ随時読み込んでいく仕組みのことです。

最初に全部いっぺんに読み込まないので、その分起動が早くなるメリットがあります。

詳しくはこちら。

Ionic and Lazy Loading Pt 1 | The Official Ionic Blog
IonicでLazy Loadingに対応する - Qiita

#Lazy Loadingの時とそうでない時のモジュール宣言の違い

AngularやIonicで使用するモジュールは、どこかでモジュールとして宣言されていなければいけません。PageとかComponentとかPipeとかDirectiveとか、全部モジュールです。

具体的には、なんとか.module.tsというファイルの中で、@NgModuleデコレータを使って

hoge.module.ts
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { HogePage } from './hoge';

@NgModule({
  declarations: [//declaration(「宣言」という意味の英単語)
    HogePage,//←宣言の中に「HogePage」を加える
  ],
  imports: [
    IonicPageModule.forChild(HogePage),
  ],
})
export class HogePageModule {}

という感じで宣言します。

この宣言を、hoge.module.tsで独自にやるか、もっと親玉のapp.module.tsでたくさんまとめて宣言するか、という違いが、Lazy Loadingかそうでないかの違いになります。

この宣言をごちゃ混ぜにして、一つのモジュールをapp.module.tsとそれぞれのmodule.tsの2箇所で宣言したりすると、エラーになります。

しかも、ionic cordova run android --deviceの時はエラーにならないのに、ionic cordova run --prod --releaseの段階になって初めてエラーになるので、気づきにくく、タチが悪いです。

エラーメッセージの例
Type Hoge in hoge.ts is part of the declarations of 2 modules: AppModule in src/app/app.module.ts and ComponentsModule in src/components/components.module.ts

##Pageのモジュール宣言
###Lazy Loading
それぞれのページについて、module.tsファイルがあり、そこで宣言する。
###いっぺんに読み込む
app.module.tsで宣言

##Componentのモジュール宣言
###Lazy Loading
それぞれのコンポーネントについてmodule.tsで宣言するか、Component用の共有モジュールcomponents.module.tsでコンポーネントたちだけ一括で宣言する

###いっぺんに読み込む
app.module.tsで宣言

###例

以下に、Component用の共有モジュールの例をあげておきます。

components.module.ts
import { NgModule } from '@angular/core';
import { HogeComponent } from './hoge/hoge.component';
import { FugaComponent } from './fuga/fuga.component';
import { FooBarComponent } from './foo-bar/foo-bar.component';
import { CommonModule } from '@angular/common';//これについては後で解説します

@NgModule({
  declarations: [HogeComponent,
    FugaComponent,
    FooBarComponent],
  imports: [CommonModule],//これについては後で解説します
  exports: [HogeComponent,
    FugaComponent,
    FooBarComponent]
})
export class ComponentsModule {}

#Lazy Loadingの時とそうでない時の、ComponentやPageの呼び出し方の違い

通常の場合、ComponentやPageを呼び出す時には、該当するものをファイルの冒頭でimportして、コード内で使います。

が、Lazy Loadingの場合は、importしようにもまだモジュールが読み込まれていないため、importに失敗します。

なので、そもそもimport文も書かず、コード内で使用する時には、文字列で指定します。

文字列でいいの!?と思ってしまいますが、それでうまくやってくれます。すごいですね。

通常読み込みの例
import { HogePage } from '..hoge/hoge';
...
  this.navCtrl.setRoot(HogePage);
...
LazyLoadingの例
//import文は不要
...
  this.navCtrl.setRoot("HogePage");
...

#IonicのLazy Loading

Ionic3では、ionic generateコマンドでpageやcomponentをgenerateすると、Lazy Loadingに対応した形でモジュール宣言が出力されます。

なので、Angularチュートリアルで勉強したようにapp.module.tsに改めて宣言を書き加えると、二重宣言でエラーになります。

結局何もしなくていいってことですね。読み込む時にimport文を書かず、呼び出しを文字列にすることだけ気をつければOK。

Componentについては、個別にmodule.tsが用意されるのではなく、コンポーネント用共有モジュールcomponents.module.tsが用意されます。

#ngIf、ngForが動かない時

詳しくはこちらに書いてあります。

要約すると、Lazy Loadingで読み込むモジュールの中で*ngFor*ngIfを使いたい場合は、そのモジュールのmodule.tsCommonModuleをインポートせよ、ということです。

Componentを共用モジュールで宣言している場合は、その共用モジュールのmodule.tsでそのimportを行うことになります。上記のコード例を再掲しておきますね。

components.module.ts
import { NgModule } from '@angular/core';
import { HogeComponent } from './hoge/hoge.component';
import { FugaComponent } from './fuga/fuga.component';
import { FooBarComponent } from './foo-bar/foo-bar.component';
import { CommonModule } from '@angular/common';//ここと

@NgModule({
  declarations: [HogeComponent,
    FugaComponent,
    FooBarComponent],
  imports: [CommonModule],//ここです。
  exports: [HogeComponent,
    FugaComponent,
    FooBarComponent]
})
export class ComponentsModule {}

#おわりに

この記事は以上です。同時に、このシリーズも以上です。

次はiOS版を作っていくことになるかな〜。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?