rdlaboさんがしっかりGW明けにIonicの記事書いてくれたので、僕もAngularのv2からv6まで、3年弱の変遷についてまとめます。
前Angular v2時代
現行Angularの歴史を話し始めるとAngularDart 0.x-1.xからの話になります。 実はAngularDart v1は、停滞したAngularJSの改革をおこなうための、仮説検証の場でした。 僕がAngularDart 0.xから1.xを使って開発していたのが2014年末〜2015年あたりなので、だいたい3年半くらい前の話です。
ここで生まれた基本的な概念は今でもしっかりとAngularに残っています。例えば次のようなもの。
これらはDartの言語機能やWeb Components仕様の整備により実装できた新しいAngularの形で、これをAngularJSの次世代バージョンとして実現するために必要な言語機能の仕様が AtScript として誕生し、これをもとにAngular 2の開発が進められました。
結局その後は紆余曲折ありAtScriptは必要なくTypeScript+デコレータで実現することになりました。
Angular v2
2015年12月に、Angular v2はbeta.0をリリースし、2016年9月14日に2.0.0がリリースされました。
ちゃんと掘り下げると無限に長くなるので、この時期に導入された重要な概念をおさらいするだけに留めます。
オフラインコンパイル
現在ではAngularのAoTコンパイルは当たり前になっていますが、当時はじめて"オフラインコンパイル"というものが発表されたときは困惑しました。 あらためて当時のプロポーザルを見ると、まさにこれって今実装されようとしているngIvyそのものじゃないかと思いました。 これまでのAoTではまだ不十分でしたが、ついに3年越しの成就となろうとしてます。感慨深い。っていうかTobias氏が頭良すぎる。
Angular 2 offline template compilation - Google ドキュメント
https://ng2-info.github.io/2016/01/angular2-in-2016/#even-faster-angular-2-tobias
実際にAoTコンパイルが使えるようになったのはrc.2からでした。2016年5月のことなので、ちょうど2年前。ngc
ちゃんも2歳になりました。
AngularJSへの .component
逆輸入
AngularJSからAngular 2への移行をスムーズにするため、マインドセットを統一するためのAPI逆輸入がおこなわれました。 コンポーネントベースの設計になることで、コンポーネントルーターを起点としたマイグレーションが可能になる、という構想でした。
当時は angular-component-router
自体は失敗しましたが、考え方自体は今のngUpgrade APIと同じなので、やっぱりAngularコアチームは頭良いですね。
Animation API
この頃、Web Animations APIを元にしたAnimation APIを作ることが決まりました。今でもしっかり続いています。
Language Service
テンプレート内でコンポーネントの型情報を元に型チェックや入力補完をおこなう機能の提案がなされたのが実はbeta.5のころです。 実際に実装されて使えるようになったのは2.3リリースの頃ですが、いまでは開発中に無くてはならないものになっています。
https://ng2-info.github.io/2016/02/beta-5-has-released/#template-services-plan
Angular CLIとスタイルガイド
John Papa氏とMinko Gechev氏のふたりが草案を作ったAngular Style Guideは、いまでも公式ドキュメントとしてメンテナンスされつづけています。 そしてAngular CLIではそのスタイルガイドに沿ったコード生成をおこなっています。
SystemJSからwebpackへ
アルファ版のころから続いていたSystemJSベースのセットアップが、webpackベースに変わりました。 v6になった今でもAngular CLIはwebpackを利用していて、Tree Shakingなどいろいろな最適化ができているのでナイスな決断だったといえます。
Forms APIの改革
RCの中でもっとも大きく変わったAPIのひとつがFormsですね。テンプレート駆動フォームと、リアクティブフォームが明確に分割され、選択できるようになりました。 この頃はテンプレート駆動がメインで、リアクティブがオプショナルという立ち位置でしたが、いまやリアクティブがメインで、テンプレート駆動がオプショナルとなりつつあります。 パラダイムの変遷を感じます。
Routerの改革
RCの中でもっとも大きく変わったAPIその2、Routerです。当時はてんやわんやでした。
AngularJS: Improvements Coming for Routing in Angular
Victor Savkin氏により実装されたRouter v3はその形をほとんど変えないまま今のv6まで続いています。 Victor Savkin氏はAngularコアチームの中でもとびきり頭が良い一人ですね。
NgModuleの導入
Angular 2のRCといえばNgModuleというくらい悪名高い破壊的変更です。いまでは当たり前ですが、これも当時は衝撃でした。
https://ng2-info.github.io/2016/07/preparing-for-ngmodule/
v6でも現役な、Angularの根幹のAPIですが、そのあり方は変わろうとしています。詳しくはv6のセクションで述べます。
Custom Elements対応
rc.6で追加されたのが CUSTOM_ELEMENT_SCHEMA
です。Angularのテンプレート内でAngularが知らないカスタム要素を使うための機能です。
これによりWeb Components仕様に則って作られたCustom Elementsとの協調が可能となりました。
いまでも現役な重要機能です。
v4
半年後の2017年3月23日にv4.0.0がリリースされました。
AngularJS: Angular, version 2: proprioception-reinforcement
AngularJS: Angular 4.0.0 Now Available
v2.xからv4の中で変わっていったものたちを振り返っていきましょう。
Reactive Angularに向けた変化
この頃からリアクティブプログラミングをサポートするための変更が進み始めます。
*ngIf
や *ngFor
が async as
記法で非同期データと値を保持できるようになったのがv4のことです。今ではこれ無しのテンプレートは考えられないです。
<div *ngIf="userList | async as users; else loading"> <user-profile *ngFor="let user of users; count as count; index as i" [user]="user"> User {{i}} of {{count}} </user-profile> </div> <ng-template #loading>Loading...</ng-template>
Angular Universalの刷新
ベータ版のころからサードパーティとして続いていたAngular Universalのコア部分をAngularコアチームが回収し、@angular/platform-server
として再実装しました。
複雑になっていたAPIを整理し、renderModule
だけを提供するシンプルなパッケージに生まれ変わりました。
platform-serverはこの頃と今でもあま変わっていませんが、platform-serverを元にした新しいAngular Universalは独自に進化を続けています。
https://github.com/angular/universal
angular.ioのAngular化
v4.2のリリースにあわせて、ようやく公式ドキュメンテーションサイトのangular.ioがAngularで再実装されました。 いまでもコアチームによるAngularのPWA実装の例として活発にメンテナンスされています。
AngularJS: Angular 4.2 Now Available
Animation APIの改革
stagger()
や group()
など複雑なアニメーションを実現するための新しいAPIがv4.2で導入されました。
A New Wave of Animation Features in Angular - yearofmoo.com
HttpClientの導入
@angular/common/http
パッケージが公開され、新しいHTTPクライアントが使えるようになったのがv4.3です。
Angular 4.3 Now Available – Angular Blog
v5
v4から半年後、2017年11月2日に2回目のメジャーアップデートであるv5.0.0がリリースされました。
Version 5.0.0 of Angular Now Available – Angular Blog
Build Optimizer
v5の頃から、Angularは機能の追加よりもバンドルサイズの改善に注力する傾向が強まります。 Build Optimizerはwebpackのプラグインとして提供され、Angularのアプリケーションのバンドル時に様々な最適化をおこない、バンドルサイズを削減します。
AngularコンパイラのTypeScript Transformer化
AngularのテンプレートコンパイラがTypeScriptの標準拡張機能に準拠することにより、デコレータのコンパイル処理に介入できるようになりました。 これはテンプレートの最適化をおこなうための足がかりでもあり、テンプレート中の無駄な空白を除去してバンドルサイズを削減することなどが可能になりました。
また、AoTコンパイルの軽量化により、ng serve --aot
が可能になったのもこの時です。
さらに、デコレータ内でアロー関数を使ってもAoTコンパイルできるようになったのもv5です。v2から長くやっている方はもしかすると無意識に避けてしまっているのではないでしょうか。
Component({ provider: [{provide: SOME_TOKEN, useFactory: () => null}] }) export class MyClass {}
ロケール依存パイプの刷新
v5で最も衝撃の強かった変更はdate
やnumber
など、ロケールに依存する組み込みパイプの全面刷新です。
それまではWeb標準仕様のI18n APIに準拠して実装されていましたが、バグが多くブラウザ間の実装の差異に悩まされていたため、それをやめてAngular内部にロケールデータを持つことになりました。
https://github.com/angular/angular/blob/master/CHANGELOG.md#i18n-pipes
Zone.js非依存化への歩み
v5では、Angularアプリケーションの実行時にZone.jsを使わない選択肢が選べるようになりました。
platformBrowserDynamic() .bootstrapModule(AppModule, {ngZone: 'noop'});
バンドルサイズの軽量化や、エキスパートな開発者による独自のパフォーマンスチューニングを可能にするための機能です。
Angular MaterialとCDK
ついにようやくAngular MaterialがStableになり、そのコアであるComponent Dev Kit(CDK)も公開されました。
Angular 5.1 & More Now Available – Angular Blog
Angular CLIのPWAサポート
Angular CLIがService Workerの生成や、Angular Universalを利用したApp Shellのレンダリングなどをサポートし、Angular for PWAの風が吹いてきました。
v6では ng add @angular/pwa
だけでPWA化が済んでしまうほどになりました。
Angular Progressive Web App Guide
v6
そして2018年5月4日、6.0.0がリリースされました。
Version 6 of Angular Now Available – Angular Blog
Angular Elements
v6といえばAngular Elementsです。 まだまだ実験的なAPIではありますが、AngularのコンポーネントをCustom Elements化できる機能が公開されています。
https://angular.io/guide/elements
アプリケーションのためのフレームワークだったAngularから、WWWの世界へ進出していくための大きな一歩です。
Angular CLIの大改革
Angular CLIがv1.7からv6へアップデートし、かなり大きな進化を遂げました。
アプリケーションだけでなくライブラリ開発も可能になり、ng update
コマンドやng add
コマンドなど新しい機能もたくさん追加されました。
新しいDI機構
NgModuleの導入以来ずっと変化のなかったDI機能に、新しい仕組みが導入されました。
Tree Shakable Providers と呼ばれる機能により、DIでプロバイドされる@Injectable
なクラスをNgModuleのproviders
に渡さなくてもよくなります。
代わりに、@Injectable({providedIn})
という新しいAPIで、自身がプロバイドされるモジュールのスコープを持つようになります。
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class MyService { constructor() { } }
Angular v6で導入されるTree-Shakable DIの紹介 - lacolaco
https://angular.io/guide/dependency-injection#tree-shakable-providers
静的な参照がNgModuleから消えるため、Tree Shakingによって実際にコンストラクタの型パラメータとして参照されているクラスだけがバンドルに含まれるようになります。
RxJS v6
Angular v6が依存するRxJSのバージョンもv6にアップデートされました。 RxJSのメンテナであるBen Lesh氏もAngularコアチームに入ったことによりスムーズに連携できるようになった印象です。
RxJS v6はTree Shakingサポートによってバンドルサイズを大きく減らすことができるため、Angularにとってもかなり嬉しいアップデートです。
まとめ
結構長くなりました。 v2以前からv6まで変化の流れを追ってみましたが、今あるAngularの機能の大半はv2のころのままですね。 新し目の機能についても構想自体はv2以前からのものもあり、2.0.0以降の変化は主に開発者支援や、バンドルサイズ削減に貢献するものがほとんどだなというのがわかります。
- v2: フレームワークとしてのAngularの完成
- v4: フレームワークのブラッシュアップ
- v5: プラットフォームとしてのAngular: Material, CDK, PWAサポート
- v6: プラットフォームの拡大: Angular Elements
といった感じでしょうか。
今後もAngularはフレームワークとしてだけでなくプラットフォームやエコシステムとして広がっていくこと間違い無しなので、マクロな視点で見ていくのが大事ですね。