5年ぶりにAngularを触ったら、審美眼もアップデートされた話
こんにちは、クレスウェア株式会社の奥野賢太郎 (@okunokentaro) です。この記事はAngular Advent Calendar 2025 24日目の記事です。
筆者は2013年頃から、AngularJSの開発案件を担当し、その流れでAngular 2以降もAngular 9まで開発案件での利用経験があります。ただ、2020年以降は取引先の技術選定やシェアの波などに飲まれ、すっかりReact + Next.jsのみを扱うようになりました。
この5年の間に、自分の中のAngularの記憶は大半が消え去っており、言われてようやく「NgModuleってあったなあ、RxJSってあったなあ」となるレベルです。
そしてさすがに数年単位でReactばかり触っていると、他の刺激も欲しいというか、隣の芝も見てみたくなるもので、今回Angularの最新版でちょっとした自分用ツールを作ってみました。その時に得た所感についてまとめていきます。
筆者の本稿のスタンスとしては、現在もさしてReact推しではなく、Angularを触れたことでAngular推しに戻ったわけでもない、中庸な立場をとっていることをご了承ください。
忘れていたはずなのに、直感的に書ける
signal() 登場による革命感
Angularを久々に触ろうと思った理由は、signal()の登場があったためでした。
筆者がパーソナリティを務めているポッドキャスト番組『リファクタリングとともに生きるラジオ』の第81回放送にて、共同パーソナリティかつAngular GDEであるlacolacoから教わったこともあり、Signalに対して「名前は聞くけど使い勝手や仕組みはあまりわかっていない」という状態だった自分は、Signal Basedなアプリケーション開発に一度触れておくべきだと感じていました。
そして2025年秋冬にかけてSolidJS, Angular 20(〜21)で小規模アプリケーションを2つ作り、そこでSignalの使い勝手、ハマりどころなどを体験しました。
Angularといえばng-modelによる「双方向データバインディング」という先入観がかなり強かっただけに、このSignal導入は「お前…ずいぶん変わっちまって…」という気持ちにすらなります。
ZonelessによるAngularの新時代
フレームワークを「Webアプリケーションを作るためのライブラリ集」として見ている間は「TODOアプリを作るとどうなる」とか「クラスベースか関数ベースか」といった方面に目が向きがちですが、長年Webアプリケーションと向き合い続けていると関心の対象は「変更検知および再描画に対する思想と取り組み」に向きます。
古いAngularオタクの発言にはなりますが、筆者がAngularを離れた時期というのは、ちょうどAngular自身がIvy乗り換えを進めていた時期でした。当時の利用者としてはIvy乗り換えは難航していたような印象を受けており「改修が大変そうだし、利用者向けのアップデートも小規模なものばかりでAngularの勢いって弱まったのかな…」と不安に思う時期もありました。従来のzone.js BasedなAngularの変更検知や、Reactの仮想DOMと関数型コンポーネントを前提とした再描画手法を長年見ていると、Angularアーキテクチャが苦難を乗り越えてSignalの導入とZonelessな変更検知を備える決断に進んだのは、まさに新時代の幕開けを感じます。
signal()関数は、React利用者向けにものすごく雑に説明するとuseState()と似たようなもの——ではありますが、その変更検知と再描画の仕組みは根本的に異なります。コード上の書き味が似ているというだけです。とはいえ、世の多くのWebアプリケーション開発者が全員フレームワークの裏のレンダリングエンジンに精通しているかというと、そんなことはないため「ReactのuseState()っぽく書けるよ」という触れ込みは「Angularってそんな特別視しなくてもいいかも」と思わせる材料としては、とてもよいと思います。
従来の変更検知を貫き、Angular Way(言い換えるとReactからはだいぶ遠い)のままにならず、Reactを長年やってても違和感なくAngular 21を始められるというのは魅力でもあり、同時にWebアプリケーション・フレームワークの収束にも感じます。もしAngularのSignal導入に興味を持ったReact利用者の読者がおられましたら、ぜひ併せてSolidJSも触ってみることをおすすめします。2025年時点でのReactの立ち位置を相対化する視点が得られると思います。
Standalone Componentの登場とNgModuleの簡便化
Angularのコミュニティに寄稿しておいて言うのもなんですが、Angularは手数が多くて面倒くさいという印象を筆者は少なからず抱いていました。その一つがコンポーネントの作成の手間です。
コンポーネントファイルを作って、CSSファイルを作って、HTMLファイルを作って、NgModuleの定義ファイルでインポートして、モジュールに追加して…。CLIを使って自動化できるとはいえ、Reactのfunction Something(): ReactElement {}と書くだけで済む手軽さを一度知ってしまうと「Angularって手間だわ…」となったものでした。
この手間は、筆者がしばらく離れていた間に解消されていました。
Angular 19以後、とうとうStandalone Componentがデフォルトで有効化され、コンポーネントはNgModuleに登録するという手間なく使えるようになりました。これもsignal()の登場 に匹敵する革命だと感じます。
Angularが14から徐々にStandalone Componentを採用していく中で、界隈のエコシステムも変化したと感じます。ひとつにTailwind CSSの台頭。これによって、筆者としてはStandalone Component一つ作り、HTMLもファイルを分けずまとめて書き、スタイルは全てTailwindクラス名で指定するというスタイルをAngularに持ち込めました。
つまりReactに慣れていても「Angular全然めんどくさくないじゃん!」となるわけです。
この反応は古いAngular(特に13より前)を印象強く持っている他フレームワークのユーザーほど顕著なのではないかなと思います。筆者も小耳に挟むレベルでAngularちょっとずつ変わってるとは聞いていましたが、もはや激変と言っていいレベルでした。「いずれ新幹線の駅ができると聞きながら都会に独り立ちし、久々に実家に戻ってきたら駅前が発展して激変していた」みたいな、ああいう感じです。
ほかにもテンプレート構文@ifや@forなど、ngIf, ngFor世代からしたら「微妙になんか変わってんな?」という箇所が多いものの、Reactを5年もしっかりやっていると、むしろ昔がどうだったかというより、Reactのノリでスラスラ書けて嬉しいという気持ちになります。過去のAngularの知識は、再キャッチアップには不要です。
「書き味」だけで選ぶ時代ではなくなった
AIに書かせておけばいいという暴論
2010年代のAngular vs Reactフレームワーク論争を真横で見てきた世代である筆者としては、当時はAPIの好み、Class Decoratorの好み、JSXの好みといった「アプリケーションを書いた時にコードベースがどんな見た目になるか」の好みで選ばれる性質があったと思います。
Angular 21に触れて、正直そこは誤差だなと感じるようになりました。Reactユーザーであればsignal()もテンプレートも1日で使い方を覚えるでしょうし、逆に長年のAngularユーザーであっても、昔よりReactにすぐ引っ越せるのではないかなと思います。つまり、useState()とかsignal()を並べて、テンプレートにバインドして「JSON色付け屋さん業」を全うできればどっちでもよいよね、となってくるわけです。
ましてや2025年から急速に普及したVibe Codingを見ていると、コードの見た目がなんであれ「書くのはどうせAIだしな」といった、人のこだわりとは離れた部分が現れ始めます。極端な話、細かい書き味がどうこうを気にせずAIに書かせておけばいいです。
AngularではAngular CLI MCPが整備され、Next.jsにもNext.js MCP Serverが整備されている点から見ても、AIモデルが既習得かどうかはもはや関係なく、AI Agentに最新の"Framework-way"を伝えてコードの作成は自動化する、といった方向性が今後のトレンドになるのは間違いないでしょう。
その中で、筆者が2025年におけるフレームワーク審美眼として、あえて意識すべきなのが「哲学」と「ガバナンス」なのではないかと思います。
Dependency Injectionの哲学
AngularはAngularJSの時代、すなわちCommonJS普及前からモジュラビリティを意識しており、同時にDependency Injection (DI)を採用しInjectabilityも兼ね備えていました。
いまやTypeScriptプログラミングにおいて、テストダブルを用いたテストの実施は当たり前のように可能で、テストの観点のみであればDIが至上価値ではないと言えるようにもなりました。しかしAngularは10年以上前から哲学としてDIを掲げ続けているのです。
それは、constructor basedなDIとしてJavaやC#方面の開発者を取り込むことに成功しましたが、Webアプリケーション開発者界隈にはconstructor basedなDIはそこまで馴染まないという層も一定数います。そこで知るべきは、現代のAngularではinject()関数が提供されており、Angular 14以降では依存を関数の戻り値として受け取ることができるということです。
inject()は、裏の仕組みを全て無視して雑にReactユーザー向けに例えるとuseContext()のようなものです。この関数のおかげでconstructorもなくなり、this.も使わない(激減させる)ことができるため、signal()と合わせてReactアプリケーションをAngularアプリケーションに移植する(あるいはその逆)は今まで以上にできるだろうなと感じました。
Angularの発展の舵取りとしてうまいなと感じたのは、constructor basedなDIにこだわりたかったわけでも、Decorator狂信者だったわけでもなく、哲学としての「DIを標準で備えたフレームワーク」を貫けるのであればAPIの形が異なってもよい、という方向に振ったことだと思うのです。
どの巨人の肩に乗るか
熱狂的なAngularファン、あるいはReactファンには申し訳ないですが、もう表面的なコンポーネントのコードの見た目がどうかは個人的には瑣末な差だと思っています。その上で現代においてフレームワークを選ぶ際の基準として「哲学」に対してもう一つ挙げられるのが「ガバナンス」だと思っています。
AngularはGoogle社が中心となってアップデートされ、一方でReact + Next.jsはMeta社(あるいはReact Foundation)やVercel社と、ステークホルダーが絡み合います。そんな中で起こった2025年12月の"React2Shell"(React RSCに起因する深刻な脆弱性問題)は無視できません。こういった問題の波及や統治のガバナンスは今後注目を集める分野になると感じます。
一社だからいい、複数社だからよくないという意味ではまったくありませんし、Meta社は脆弱性を仕込んでGoogle社は仕込まないという意味でもまったくありません。そこは誤解を招きたくないのですが、とはいえシェアを握っているエコシステムに対する深刻な脆弱性が起こった際に、それがどのように対策され収まっていくか、それを誰がやるのか、誰が責任をとるのか、といった関心はこれまで以上に注目せざるを得ないでしょう。
もはや「どこの馬の骨かもわからない」フレームワークは選びにくい時代なのではないでしょうか。どの巨人の肩に乗るか、巨人の肩の乗り心地や、巨人の肩からの眺めはどんなものか。巨人の肩という観点が、これまで以上に現代的なフレームワーク選択での審美眼に組み込まれていくでしょう。
審美眼のアップデート
久しぶりにAngularを触って気づいたのは、技術そのものの進化に対する驚きだけでなく、それを評価する自分の目の変化でした。2010年代の気持ちのまま「Angularってこうだよね、Reactってこうだよね」と2025年になって語ってしまう危うさ——Angular 21を触ることによってそこに気付くきっかけを得られたのは、貴重な経験だったと思います。
最後に、ここまで読んで「じゃあAngularとReactどっちがいいの」とまだ迷われている読者がおられましたら、一つお伝えします。毎年このAngularアドベントカレンダーは豊富に書かれており、初代から合計すると200以上の記事があります。もしあなたがそのコミュニティの厚さに惹かれたなら、それを信じてよいのではないでしょうか。
本稿は以上です。最後までお読みくださいましてありがとうございました。
Discussion