SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

次世代Webアプリケーションフレームワーク「Angular」の活用

「Angular」バージョン15・16の新機能は?──スタンドアロンコンポーネントとSignalでより学びやすく!

次世代Webアプリケーションフレームワーク「Angular」の活用 第27回

  • X ポスト
  • このエントリーをはてなブックマークに追加

 本連載では、Webアプリケーションフレームワーク「Angular」の活用方法を、サンプルとともに紹介しています。前回紹介したバージョン14に引き続き、今回は2022年11月リリースのバージョン15と、2023年5月にリリースされたばかりのバージョン16について、変更点や新機能を紹介していきます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 Angularは、Googleとオープンソースコミュニティで開発されているJavaScriptフレームワークです。最初のバージョンはAngularJS(AngularJS 1)と呼ばれていましたが、バージョン2で全面的に刷新され、以降、おおむね半年に1回アップデートされています。

 2022年7月の前回記事では、Angularのバージョン14について、変更点や新機能を紹介しましたが、その後Angularは2022年11月にバージョン15、2023年5月にバージョン16がそれぞれリリースされました。本記事では、Angularのバージョン15および16(以下「Angular 15」「Angular 16」と記述)について、主要な変更点や新機能を説明していきます。なお、各バージョンのより詳細な情報や変更点は、Angularの公式ブログ記事(Angular 15Angular 16)を参照してください。

対象読者

  • Angularの最新動向を定期的にチェックしておきたい方
  • 既存のAngularソースコードを最新版に追従する必要がある方
  • より便利にAngularを活用したい方

必要な環境

 Angularの開発では、一般にTypeScript(変換してJavaScriptを生成する、いわゆるAltJS言語)が利用されます。本記事のサンプルコードもTypeScriptで記述しています。

 今回は以下の環境で動作を確認しています。基本的にはAngular 16を利用しますが、比較のため一部のサンプルでAngular 14を利用しています。

  • Windows 10 64bit版
  • Angular 16.0.0、14.0.7
  • Angular CLI 16.0.0、14.0.0
  • Node.js v18.16.0
  • Microsoft Edge 112.0.1722.68

 サンプルコードを実行するには、サンプルのフォルダーで「npm install」コマンドを実行してライブラリーをダウンロード後、「ng serve」コマンドを実行して、「https://localhost:4200」をWebブラウザーで表示します。

Angular 15の新機能

 以下では、Angular 15の主要な新機能や変更点を紹介していきます。

正式版になったスタンドアロンコンポーネント

 モジュール(NgModule)を利用せずにコンポーネントを記述できるスタンドアロンコンポーネントは、Angular 14で開発者プレビューが提供されていましたが、Angular 15で正式版になりました。本記事では、NgModuleを利用した従来のプロジェクトを、スタンドアロンコンポーネントを利用するよう変更する方法を説明します。なお、スタンドアロンコンポーネントの記述方法はAngular 14の時点からほぼ変わらないため、Angular 14の解説記事も参考にしてください。

 まず、AngularのWebアプリを起動するmain.tsの処理は、リスト1の通り変更します。従来のアプリ起動処理(1)に代わり、(2)の通りboostrapApplicationメソッドの引数に最初に表示するコンポーネント(ここではAppComponent)を指定して実行します。

[リスト1]スタンドアロンコンポーネントでWebアプリを起動する処理(p001-standalone/src/main.ts)
// モジュールを利用した従来のアプリ起動 ...(1)
// platformBrowserDynamic().bootstrapModule(AppModule)
//   .catch(err => console.error(err));
// スタンドアロンコンポーネントを利用したアプリ起動 ...(2)
  bootstrapApplication(AppComponent)
    .catch(err => console.error(err));

 次にAppComponentをリスト2の通り修正して、スタンドアロンコンポーネントにします。@Componentデコレーターで、(1)のstandalone属性をtrueに設定すると、コンポーネントがスタンドアロンコンポーネントになります。コンポーネントで利用する別のコンポーネントやモジュールは、(2)のimports属性に指定します。ここではngIfやngForが定義されているCommonModuleをインポートしています。

[リスト2]AppComponentをスタンドアロンコンポーネントにする実装(p001-standalone/src/app/app.component.ts)
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  standalone: true, // スタンドアロンコンポーネントを指定 ...(1)
  imports: [CommonModule] // CommonModuleをインポート ...(2)
})
export class AppComponent {
  title = 'p001-standalone';
}

 リスト1、2の変更後Webアプリを起動すると、Webページの見た目は全く変わりませんが、AppComponentがスタンドアロンコンポーネントとして動作するようになります。

[補足]スタンドアロンコンポーネントの利用をサポートするCLIコマンド

 Angular 15の時点では、スタンドアロンコンポーネントを生成するための--standaloneオプションがAngular CLIで利用できました。

[リスト3]スタンドアロンコンポーネントを生成するコマンド
ng g component <コンポーネント名> --standalone

 さらにAngular 16では、スタンドアロンコンポーネント関連のCLI機能が拡張されました。リスト4のコマンドにより、スタンドアロンコンポーネントを最初から利用するようにプロジェクトを生成できます。

[リスト4]スタンドアロンコンポーネントを利用するプロジェクトを生成するコマンド
ng new <プロジェクト名> --standalone

 また、既存プロジェクトのフォルダーでリスト5のコマンドを実行すると、スタンドアロンコンポーネントを利用するように既存プロジェクトを変換できます。

[リスト5]スタンドアロンコンポーネントを利用するよう既存プロジェクトを変換するコマンド
ng g @angular/core:standalone

複数ディレクティブを合成できるDirective composition API

 Angular 15で提供されたDirective composition APIを利用すると、複数のディレクティブを合成して新たなディレクティブにしたり、コンポーネントにディレクティブを合成したりできます。図1のサンプルで利用法を説明します。

図1 Directive composition APIのサンプル(p002-directive)
図1 Directive composition APIのサンプル(p002-directive)

 このサンプルでは、テキストの色を指定するhlcolorディレクティブと、フォントを指定するhlfontディレクティブを実装します。hlcolorディレクティブの実装はリスト6の通りです。コンストラクターでディレクティブが適用されるHTML要素をelに取得し、CSSのcolor属性を「red」にして、文字を赤色にしています。hlfontディレクティブも同様の実装で、太字、フォントサイズ20ptを指定します(実装はサンプルコードを参照)。

[リスト6]hlcolorディレクティブ(p002-directive/src/app/hlcolor.directive.ts)
@Directive({
  selector: '[appHlcolor]',
  standalone: true
})
export class HlcolorDirective {
  constructor(private el: ElementRef) {
    this.el.nativeElement.style.color = 'red';
  }
}

 Directive composition APIでディレクティブを合成するには、リスト7の通り実装します。(1)のhostDirectives属性に指定した複数のディレクティブが合成されます。

[リスト7]hlcolorとhlfontを合成したhighlightディレクティブ(p002-directive/src/app/highlight.directive.ts)
@Directive({
  selector: '[appHighlight]',
  standalone: true,
  hostDirectives: [  // ...(1)
    HlcolorDirective,
    HlfontDirective
  ]
})
export class HighlightDirective {
}

 リスト7のhighlightディレクティブをHTML要素にリスト8の通り適用すると、hlcolorとhlfontの両方の効果が表れ、赤字、太字、フォントサイズ20ptで表示されます。

[リスト8]highlightディレクティブをHTML要素に適用(p002-directive/src/app/app.component.html)
<p appHighlight>これも大事なことです</p>

 hostDirectives属性をコンポーネントで利用すると、複数ディレクティブの効果をコンポーネントに適用できます。リスト9の場合、コンポーネントに含まれる文字列が赤字、太字、フォントサイズ20ptになります。

[リスト9]hlcolorとhlfontディレクティブをコンポーネントに適用(p002-directive/src/app/sub.component.ts)
@Component({
  selector: 'app-sub',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './sub.component.html',
  styleUrls: ['./sub.component.css'],
  hostDirectives: [
    HlcolorDirective,
    HlfontDirective
  ]
})
export class SubComponent {
}

 Directive composition APIのより詳細な利用法は公式ドキュメントを参照してください。なお、Directive composition APIは、スタンドアロンのディレクティブのみで利用できます。

画像を最適化するNgOptimizedImage

 Webページ上の画像を最適化してページの読み込み速度を上げる、NgOptimizedImageディレクティブが利用できるようになりました。@Componentデコレーターのimports属性にNgOptimizedImageを追加後、テンプレートにリスト10の通り記述して利用します。通常の<img>タグ(1)では画像ファイルのパスをsrc属性に指定しますが、NgOptimizedImage(2)ではngSrc属性に指定します。

[リスト10]NgOptimizedImageの利用(p003-image/src/app/app.component.html)
<h3>【このページの下部に画像があります】</h3>
<p>(略:長い文字列)</p>
<h3>通常のimgタグによる画像表示</h3>
<img src="assets/image1.jpg" width="320" height="240"> <!--(1)-->
<h3>NgOptimizedImageによる画像表示</h3>
<img ngSrc="assets/image2.jpg" width="320" height="240"> <!--(2)-->

 リスト10のWebページは、長い文字列の下に画像が配置されます。ページ表示後、開発者ツールで確認すると、(1)で参照したimage1.jpgはページ表示と同時にダウンロードされますが、(2)で参照したimage2.jpgはすぐにダウンロードされず、ページを下にスクロールしていく(つまり、画像が見えそうになる)ときに遅延ダウンロードされます(図2)。この処理により、最初にWebページが表示されるまでの時間を短縮できます。

図2 NgOptimizedImageによる画像の遅延ダウンロード(p003-image)
図2 NgOptimizedImageによる画像の遅延ダウンロード(p003-image)

より見やすくなったスタックトレース

 Angular 15(正確には14.1)以降では、ChromeやEdgeといったブラウザーの開発者オプション機能と連携して、フレームワーク側のスタックトレースを非表示にして、開発者が自分のコードのスタックトレースをより追いやすいようにしました。この機能を利用するには、まずブラウザーの開発者ツールで設定画面を開き、「Ignore List(無視リスト)」で「リストの無視を有効にする」「既知のサードパーティー スクリプトを~」をチェックします(デフォルトでチェックされています)。

図3 Microsoft EdgeのIgnore Listオプション
図3 Microsoft EdgeのIgnore Listオプション

 Webページでスタックトレースを出力させると、Angular 14ではフレームワーク側を含めた大量のスタックトレースが出力されます。

図4 Angular 14のスタックトレース出力(p004-stacktrace-14)
図4 Angular 14のスタックトレース出力(p004-stacktrace-14)

 一方、Angular 14.1以降では、開発者のソースコードに関連したスタックトレースのみ出力されます。

図5 改善されたスタックトレース出力(p004-stacktrace)
図5 改善されたスタックトレース出力(p004-stacktrace)

 なお、図4、5に示したスタックトレースを出力するWebページの詳細は、サンプルコードを参照してください。

MDCベースの新しいAngular Materialコンポーネント

 Angular Materialのコンポーネントが「Material Components for the Web」(MDC)をベースにリファクタリングされました。この変更は、Angular 13の過去記事で「アクセシビリティ改善を開発中」と紹介しましたが、この開発が完了し、正式版として利用できるようになりました。新旧のラジオボタンを表示する図6のサンプルで利用法を説明します。新しいラジオボタンは間隔が空いていて、タッチ操作時のアクセシビリティに配慮されています。

図6 新旧Angular Materialコンポーネントの比較(p005-material)
図6 新旧Angular Materialコンポーネントの比較(p005-material)

 新旧のAngular Materialコンポーネントを表示するテンプレートの記述は共通で、リスト11の通りです。<mat-radio-group>、<mat-radio-button>コンポーネントを利用します。

[リスト11]Angular Materialコンポーネントの利用(p005-material/src/app/sub.component.html、sub-legacy.component.html)
<mat-radio-group [(ngModel)]="selectedValue">
  <div>
    <mat-radio-button value="0">Galaxy S23 Ultra</mat-radio-button>
  </div>
(略)
</mat-radio-group>

 新しいコンポーネントを利用する場合、リスト12の通り、@Componentデコレーターのimportsに、MatRadioModuleを指定します。

[リスト12]新しいAngular Materialコンポーネントの参照(p005-material/src/app/sub.component.ts)
import { MatRadioModule } from '@angular/material/radio';
@Component({
  imports: [CommonModule, FormsModule, MatRadioModule],
(略)
})

 古いコンポーネントを参照する場合はリスト13の通り、MatLegacyRadioModuleを指定します。

[リスト13]古いAngular Materialコンポーネントの参照(p005-material/src/app/sub-legacy.component.ts)
import { MatLegacyRadioModule } from '@angular/material/legacy-radio';
@Component({
  imports: [CommonModule, FormsModule, MatLegacyRadioModule],
(略)
})

[補足]古いコンポーネントへのテーマ適用

 リスト13で指定した古いAngular Materialコンポーネントにはデフォルトでテーマが適用されないため、ページ全体のSCSS指定(src/styles.scss)で、古いコンポーネントにもテーマを適用する記述が必要となります。詳細はサンプルコードを参照してください。

次のページ
Angular 16の新機能

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
次世代Webアプリケーションフレームワーク「Angular」の活用連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/17782 2023/05/29 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング