emahiro/b.log

Drastically Repeat Yourself !!!!

Vuetify プロジェクトの依存の整理でハマった話

Overview

タイトルの通りです。
業務で Vuetify を使ったプロジェクトの依存整理をしていたのでそこではまったところをメモりました。

ちなみに当初のモチベーションはようやく?そろそろ? Vuetify が Vue3 に対応しそうなのでリリース時にすぐに移行できる準備として現行のプロジェクトの依存を整理したかった、というものです。
ちなみに今現在 beta すらタスク半分くらい残ってるけど大丈夫なんだろうか...。

github.com

やったこと

TypeScript 3.9.3 -> 4.6.2 (202203時点の最新)にする。

まず最初に npm audit fix したり snyk(dependabot みたいなやつ)からサジェスチョンされていた coposition-api 系のライブラリがを上げようとしたところ、構文エラーが多発してしまって詰まったのですが、こちらはプロジェクトで使用していた TypeScript のバージョンが 3系だったからでした。

そのため、まずはTypeScript のバージョンを 3系から4系にアップデートして composition-api 周りの依存をアップデートしました。

下に記述してますが、TypeScript のアップデート時に既存の IE 向けの処理が一部 API の互換がなくなってエラー発生するようになりましたが、IE 向けの機能だったのでサポート切って実装を削除しました。

TypeScript のバージョンを上げただけで composition-api が最新になったのでさっさと上げておけばよかったなと後悔しました。

TypeScript を最新にしたら IE 対応用のメソッドが動かなくなった。

stackoverflow.com

TypeScript 4.3 -> 4.4 の間で変更があったこと知りませんでした。特にサポートする必要もなかったので IE 用の実装は削除しました。

Axios を使った API リクエストのレスポンスが unkown 型になってしまった

axios を使った API クライアントのレスポンスの例外処理において unkown 型を一部返すようになった(おそらく TS を最新にした際に諸々の依存が引きづられてアップデートされた関係)ので、API クライアントの異常系の処理において unknown の場合のハンドリングが必要になりました。

これはクラメソさんがAxiosを使った際の unknown 型のハンドリング方法をまんま公開してくれてめちゃくちゃ助かりました。

dev.classmethod.jp

try {
    // try request
} catch(e) {
    if (Axios.isAxiosError(e) && e.response) {
         // e.response.status の中を見て StatusCode ごとのエラーハンドリングをする
    }
}

vue-type-check が TS4系に対応していなかったので vue-tsc に移行

github.com

vue-tsc 採用前には、この辺でまとめられていた vue-type-check を SFC ファイルの解析のために利用してました。ただ後述しますが現時点では TypeScript の最新版に対応してません。この Qiita のエントリ自体も流石に古いのでもう参照する方も少ないのかもしれませんが。。。

qiita.com

しかし TypeScript を最新に引き上げてからどうにも vtc コマンドの実行で転けるようになり、調べると TypeScript の最新おろか 4 系にも対応してないことがわかったので一思いに外しました。 issue は上がってますけどどうやら 202203 時点では反応なく、メンテされ続けるかも怪しかったのもあります。
issue に動きがあったらまた採用を検討しようかなと思います。

github.com

vue-tsc の導入にはビザスクさんが出していたこちらのエントリを参考にさせてもらいました。

tech.visasq.com

vue-tsc で気になったところ

上記のビザスクさんのエントリでも記載されてる内容ですが、vue-tscSFC も解析対象に入れてくれるのはめちゃくちゃありがたいんですが、無名関数だと any 警告出るようになっちゃうところですね。

例えば以下のような実装だと implicit any の警告が出てしまいます。

<v-text-field
                type="string"
                label="key"
                :key="key"
                @change="v => (state = v)">
</v-text-field>

対応策としては methods に関数を追加し、@change="foo" みたいな実装にする他ないですが、v-for で loop した時の要素を追加する場合には実装状関数として切り出すのも難しい( @change="foo(v, state)" みたいな実装はできない)ので既存プロジェクトで全てを変更するのはコストだなと思い、一時的にプロジェクト全体で implicit any の option は off にしました。 Vue3 になれば SFC も TS 互換になるのでこの辺の型明示ができるはず?なのでそれを待つことにします。一旦 any については SFC は見ず、実装面ではレビューで担保しよう、と言う方針にしました。
ゆーて 2ヶ月後には Vuetify の Vue3 対応が出るはずですし...(しかし延びに延びてるのでちゃんと出るのか不安ですが...)

jest 周りの依存を整理する 

production のビルドは大体通るようになったのですが、jest でのテスト周りが転けるようになったので以下で一気に jest 周りのライブラリも全部アップデートしました。

npm i --save-dev @vue/vue2-jest@latest @types/jest@latest ts-jest@latest

まとめ

フロントエンドのプロジェクトの依存の整理は毎回迷路を解いてる気分になります。
一方でどうせしんどいのはわかっていたので、基本的には公式の提供するライブラリ以外は使わない(Vuetify が用意してくれてる便利 API 系)と言う選択をしていたのもあり、比較的短期間で上げられた(実質1dayくらい)と思います。

この手の依存の整理は何度目かなんですが、node バージョン依存だったり、TypeScript のバージョン依存だったりと、本筋と関係ないところでハマるのでライブラリのメンテナンス度等を加味しつつ、便利でもいつメンテされなくなるかわからないものを利用するよりは、大きなプロジェクトの謹製ライブラリに寄っておくのが安牌だなと再認識しました。