はじめに
Angularは、Googleとオープンソースコミュニティで開発されているJavaScriptフレームワークです。最初のバージョンはAngularJS(AngularJS 1)と呼ばれていましたが、バージョン2で全面的に刷新され、以降、おおむね半年に1回アップデートされています。
2020年12月の前回記事ではバージョン10・11の変更点や新機能を紹介しましたが、それから約1年を経過した現在、Angularは2021年5月にバージョン12、11月にバージョン13と、順当にバージョンアップを重ねました。本記事では、Angularのバージョン12および13(以下「Angular 12」「Angular 13」と記述)について、主要な変更点や新機能を説明していきます。
対象読者
- Angularの最新動向を定期的にチェックしておきたい方
- 既存のAngularソースコードを最新版に追従する必要がある方
- より便利にAngularを活用したい方
必要な環境
Angularの開発では、一般にTypeScript(変換してJavaScriptを生成する、いわゆるAltJS言語)が利用されます。本記事のサンプルコードもTypeScriptで記述しています。
今回は以下の環境で動作を確認しています。基本的にはAngular 13を利用しますが、比較のため一部のサンプルでAngular 12、11を利用しています。
- Windows 10 64bit版
- Angular 13.2.5、12.2.16、11.1.2
- Angular CLI 13.2.5、12.2.16、11.1.2
- Node.js v16.14.0
- Microsoft Edge 99.0.1150.36
サンプルコードを実行するには、サンプルのフォルダーで「npm install」コマンドを実行してライブラリーをダウンロード後、「ng serve」コマンドを実行して、「https://localhost:4200」をWebブラウザで表示します。
実装時に便利なAngular 12の新機能
以下では、Angular 12で導入された新機能のうち、実装時に役立つものや、開発者の対応が必要となるものを中心に説明していきます。
国際化IDの移行ツール
Angularには国際化(internationalization、i18n)機能があります。図1のサンプルは、「ng serve」で実行すると英語で表示しますが、「ng serve --configuration=ja」とオプションを指定して実行すると、国際化機能により日本語で表示されます。国際化機能を利用する方法の詳細は、サンプルコードのREADME.mdを参照してください。
日本語のリソースは、プロジェクト内のmessages.ja.xlfに、リスト1の通り定義されています。<trans-unit>要素のid属性に対応して、<source>要素内に文言が記述されます。
<trans-unit id="50a73c21c896237d8bccf25fad9cb416bbcb6764" datatype="html"> <source>国際化サンプル</source> (略) </trans-unit>
Angular 10以前ではこのIDの形式に不具合があり、Angular 11以降で新規に生成されたプロジェクトではIDの形式が変更されました。Angular 12では、このIDを旧型式から新形式に変換する手段が提供されました。まずリスト2のコマンドを実行して、新旧国際化IDの対応付けが記述されたmessages.jsonファイルを生成します。
ng extract-i18n --format=legacy-migrate
messages.jsonファイルを引数に指定してリスト3のコマンドを実行すると、リソースファイルのID(リスト1のid属性)を新形式に変換します。
npx localize-migrate --files=*.xlf --mapFile=messages.json
最後に、tsconfig.jsonの「enableI18nLegacyMessageIdFormat」をfalseにして、旧型式のID利用を無効にします。
"angularCompilerOptions": { // "enableI18nLegacyMessageIdFormat": true, // 古い形式のメッセージIDを利用 "enableI18nLegacyMessageIdFormat": false, (略) }
テンプレートでのNull合体演算子
Null合体演算子(&&)は、「a && b」としたときに、aがnull以外ならばa、nullならばbを返却する演算子です。この演算子はもともとTypeScriptファイル(*.ts)内で利用できましたが、Angular 12では新たにテンプレートファイル(*.html)内でも利用できるようになりました。
この例を、図2のサンプルで説明します。テキストボックスに入力した文字列をそのまま(空文字の場合も含めて)画面に表示しますが、ボタンを押して名前をnullにしたときは「【名前はnullです】」と表示されます。
このサンプルのテンプレートはリスト5の通りです。Null合体演算子により、名前の変数yourNameがnullの時に「【名前はnullです】」が表示されるよう記述されています。
<div>あなたの名前は: {{ yourName ?? '【名前はnullです】' }}</div>
インラインSassのサポート
Sassは、変換してCSSを生成する、いわゆるAltCSSです。これまではSassの利用が外部スタイルファイル(*.scss)に限られていましたが、Angular 12でコンポーネント内に直接Sassを記述できるようになりました。図3のサンプルで説明します。
図3のサンプルのコンポーネントファイル(app.component.ts)には、リスト6の通り、styles属性にSass(scss)形式でスタイルが直接記述されています。Sassでは階層構造を指定でき、ここではparentクラスが適用された<div>タグ配下に、childクラスが適用された<div>タグがある場合、文字色を赤くする指定を行っています。
@Component({ (略) styles: [` div.parent { div.child { color: red; } } `] }) (以下略)
対応するテンプレートはリスト7の通りです。リスト5のSass指定により、(1)にはスタイルが適用されて文字色が赤くなります。同じchildクラスが適用されていても、上位<div>タグのクラスが異なる(2)にはスタイルが適用されません。
<div class="parent"> <div class="child"> スタイルが適用されて赤色になる <!--(1)--> </div> </div> <div class="other-parent"> <div class="child"> スタイルが適用されず、赤くならない <!--(2)--> </div> </div>
CSSフレームワークTailwind CSSのサポート
Angular 11.2以降では、CSSフレームワークのTailwind CSSをサポートしました。図4はTailwind CSSの利用例です。
図4のテンプレートはリスト8の通りです。(1)は<h1>タグですが、Tailwind CSSによってスタイルが削除されます。また(2)では「ml-5」で左マージンが、「text-red-500」でテキスト色が設定されます。
<h1>Tailwind CSSサポート(※h1タグの書式が削除)</h1><!--(1)--> <div class="ml-5 text-red-500"><!--(2)--> 左マージンが5(=1.25rem)、赤色(R239,G68,B68) </div>
AngularでTailwind CSSを利用するには、「npm install tailwindcss」でインストール後、設定ファイルtailwind.config.jsを配置し、CSSファイル(style.css)でTailwind CSSを参照します。詳細はサンプルコードのREADME.mdを参照してください。
Angular CDK/MaterialのSassモジュールシステムと「@use」対応
Angular CDK/Angular Materialが、Sassの新しいモジュールシステムに対応しました。この変更を、Angular Materialのテーマを変更する、図5のサンプルで説明します。左のボタンが「primary」、右のボタンが「accent」の色で指定されています。
Angular Materialのスタイルを変更するには、Angular 12ではstyles.scssファイルにリスト9の通り記述します。(1)の@useでAngular Materialからスタイルを「mat」としてインポートし、「mat.core()」でベーススタイルを設定します。(2)でprimary、accentのカラーパレットを設定し、それらより(3)でテーマを$my-themeとして生成します。生成したテーマは(4)でコンポーネント共通テーマとボタンテーマに設定します。
// ベーススタイルをインポート・設定 ...(1) @use '@angular/material' as mat; @include mat.core(); // primary, accentに対応するパレットを設定 ...(2) $my-primary: mat.define-palette(mat.$pink-palette); $my-accent: mat.define-palette(mat.$blue-palette); // パレットからテーマを生成 ...(3) $my-theme: mat.define-light-theme(( color: ( primary: $my-primary, accent: $my-accent ) )); // 生成したテーマをコンポーネント共通テーマ、ボタンテーマに設定 ...(4) @include mat.core-theme($my-theme); @include mat.button-theme($my-theme);
同様の設定を、Angular 11ではリスト10の通り記述していました。(1)の@importは古い記述で、Angular 12ではリスト9(1)の@useに置き換えられます。
// ベーススタイルをインポート・設定 ...(1) @import '~@angular/material/theming'; @include mat-core(); // primary, accentに対応するパレットを設定 ...(2) $my-primary: mat-palette($mat-pink); $my-accent: mat-palette($mat-blue); // パレットからテーマを生成 ...(3) $my-theme: mat-light-theme(( color: ( primary: $my-primary, accent: $my-accent ) )); // 生成したテーマを設定 ...(4) @include angular-material-theme($my-theme);