📑

Angularを8から15にアプデした話とFirebaseに苦戦した話

2024/05/17に公開

はじめに

どうもReactをRailsに書き換えたり、Angularを8から15にアップデートできる系、React専門のフロントエンドエンジニアです
タイトルの通り先日Angularを8から15にアプデしたのでその話を書きます

概要

なんでアプデしたのかを軽く紹介

なんでそんなに古いの?

誰も触ってない部分で、本番でも特に不具合なく動いていたので放置されて、めちゃめちゃ古くなっていました。。。

なぜ急にアプデを?

2024/01/31からGoogle App Engine(GAE)でNode v18未満のサポートが終わりました
これにより新規のデプロイが通常の手段では出来なくなり、流石にあげるかとなりアプデすることになりました

アプデの仕方

Angularには嬉しいことに公式のアプデツールが用意されています

ng update @angular/core@バージョン @angular/cli@バージョン

大抵の機能はこのコマンドを8から9、9から10、….と一個ずつ叩いていくだけでいい感じに上がっていきます
なので本体のアップデートはそこまで大変ではないです。

このサイトが便利です

https://update.angular.io/

formの初期化が途中変わったりとか、いくつかの機能が非推奨になっていたりとかはあるので、それについては公式のドキュメントを参照してください
そこそこ大きなアプリでしたが、Angular本体は特に大きな問題は起きずにアプデできました
アプデの中で少しずつ機能が追加されたり、変わったりしていくのを見てるのは歴史を感じて楽しいですね

周辺のライブラリのアプデ

TSLintをESLintに変更

TSLintが非推奨になったのでESLintに変更しました
ここを参考にして変更しました

https://github.com/angular-eslint/angular-eslint/blob/main/docs/MIGRATING_FROM_TSLINT.md

地味にルールが違って通らないところがあったので、都度無効化するか、修正するか判断していきました

Sassをアプデ対応

バンドルされてるSassがアプデされた影響で、一部のSassの記法が通らなくなりました
例えば以下のような記法が通らなくなりました

@import "~src/styles/variables";

相対パスに変更するか、~を削除するかで対応しました

Firebaseをアプデ

ここからが本題です
Firebase SDK を8→9にアプデするのが地獄でした

なぜ地獄だったのか

Firebase SDK 9からは全てのモジュールがESモジュールになりました
例えばドキュメントにデータを追加する場合、v8では以下のように書いていました

v8

db.collection("users").add({
    first: "Ada",
    last: "Lovelace",
    born: 1815
})
.then((docRef) => {
    console.log("Document written with ID: ", docRef.id);
})
.catch((error) => {
    console.error("Error adding document: ", error);
});

これをv9にアプデすると以下のように書かないといけません

v9

import { collection, addDoc } from "firebase/firestore";

try {
  const docRef = await addDoc(collection(db, "users"), {
    first: "Ada",
    last: "Lovelace",
    born: 1815
  });
  console.log("Document written with ID: ", docRef.id);
} catch (e) {
  console.error("Error adding document: ", e);
}

angular fireもv9アプデに合わせて大幅に書き方が変わったので本当に大変でした
Firebase関連のアプデだけでこの変更

辛かった変更を一部抜粋して紹介します

Timestampの変更

Timestampの型がDateから{seconds: number, nanoseconds: number}に変更されました
Dateとして扱っていた部分で引き続き使えるように関数を作成しました

export interface FirebaseTimestamp {
  seconds: number;
  nanoseconds: number;
}

export function convertFirebaseTimestampToDate(timestamp: FirebaseTimestamp | Date): Date {
  if (timestamp instanceof Date) {
    return timestamp;
  }
  const date = new Date(timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000);
  return date;
}

すでにDate型として代入している部分もあったので、影響を抑えるためにUnionで許容するようにしました

リアルタイムデータの変更

snapshotの取得方法が変わりました
元々angular fireの機能を使っていましたが、v9のアプデでfirebaseの機能を使うように変更しました

v9

import { doc, onSnapshot } from "firebase/firestore";

onSnapshot(doc(db, "cities", "SF"), (doc) => {
  console.log("Current data: ", doc.data());
});

まとめ

Angularのアプデは本体のアプデはそこまで大変ではないですが、周辺のライブラリのアプデが地獄でした
適度にアプデしていくことが大事ですね

ReactをRailsにした話はこちら

https://zenn.dev/gmomedia/articles/5a6819c5a9e9ad

GitHubで編集を提案
GMOメディアテックブログ

Discussion