2024.12.24
ビジネスが急速に変化する現代は「OODAサイクル」と親和性が高い 流通卸売業界を取り巻く5つの課題と打開策
3万行のJavaScriptをTypeScriptにするときに気を付けた5つのこと(全1記事)
リンクをコピー
記事をブックマーク
東川翔氏(以下、東川):「JavaScriptからTypeScriptの移行のプロジェクトに関して気を付けた点」について話していきます。
まず自己紹介です。東川と申します。新卒の2年目で新規旅行アプリの開発をしています。興味のある言語はTypeScriptやPostgreSQLです。最近はクライアントアプリケーションの構築にも興味があって、Next.jsに関してアドベントカレンダーを書いています。
今日お話しする概要ですが、マイクロサービスの1つをJavaScriptからTypeScriptに移行した内容をお話しします。状況ですが、新規の旅行アプリの開発が走っていて、マイクロサービス化された1つを除いて、画面やフロントサーバーのアプリケーションなどはTypeScriptで開発されていたんですが、一番大きなサービスがJavaScriptのままで残っていました。
既存のアプリから移植して開発を続けていたため、もともとのJavaScriptのアプリケーションが残っていたのです。開発を続けていく中で、チームのメンバーから「他はTypeScriptでここだけがJavaScriptだと、このサービスだけ型がなくてツライ」という声が上がってくるようになりました。
このようにしてTypeScriptの移行のプロジェクトが立ち上がりました。メンバー全員に対して「JavaScriptからTypeScriptに移行するかどうか」という質問を投げたんですが、意外にもTypeScript化に対して反対意見は出ませんでした。これはなぜかというと、型のある開発の恩恵をメンバー全員が感じていたからだと思います。
そもそも、なぜTypeScriptにするのかというと、型を付けるコストをはるかに上回るメリットがあるからだと思います。1つ目に、型推論があることによってバグを予防できます。例えば大きなアプリケーションだとこの変数がnullやundefinedになりうるかどうかをいちいち覚えておくのは大変です。またアプリケーションが大きい場合、オブジェクトの中身やオブジェクトのキーなどをいちいち覚えておくのも大変です。
TypeScriptであれば、強力なエディタの補完によってこれを解消できます。また、型は簡易的な仕様書としても機能します。型を裏切るようなコードは、トランスパイルで落ちるため書けません。すなわち型はアプリケーションの実際の挙動と密接に関係した仕様書になっている、ということです。
これは大人数や長期間のプロジェクトでより効果的です。例えば初めてチームにジョインしたメンバーも、型があるので関数の挙動を理解しやすく、開発がスッと始められるという利点がありました。またAPIリクエストを実際にしなくてもレスポンスの型が提供されていれば、クライアントのアプリケーションだけを先行開発することも可能です。
今回のJavaScriptからTypeScriptの移行はなかなか大変だったんですが、やってよかったと思ったことを5つ紹介します。まず1つ目に「アプリの設計やドメイン知識の強い人に相談をする」ことです。TypeScript化は、実は.jsを.tsにして、出てきた型エラーを潰すだけの作業ではなく、もっと複雑です。
なぜかというと、ある部分に型を付けようとすると、そこを参照している型を付ける必要がありますが、参照先を参照しているまた別のところに型を付ける必要が出てきたりと、順番をきちんと整理しないと型を付ける作業量が膨れ上がります。
これをTypeScript化しやすい単位に切り出して、部分的に型を付けるためにはアプリ全体の理解が不可欠です。目についたファイルからとりあえずTypeScript化するのではなく、きちんとアプリの設計やドメイン知識を勉強して、処理が独立しているAPIを見抜いてTypeScript化するようなプロセスを踏むのが非常に有効だと感じています。
2つ目に、「本当にできるかトライアル移行で試す」のが有効かなと思います。JavaScriptのアプリケーションは、ものによっては数万から数十万行の分量をもつ場合があります。すなわちやってみないとわからないことが多いということです。まずは小さいAPIや小さいページに対してTypeScript化の素振りをします。
素振りをして、その結果から全体を移行する期間と実装量を見積もります。今回の場合、実際にAPIを1本リクエストからレスポンスまでTypeScript化してみました。そこからTypeScript化が実際に可能であること、始めるとしたらここからがよい、あるいはたぶんここが難しいという感覚をつかめました。これは全体をTypeScript化する上で、非常に有効だったと感じています。
3つ目ですが、「一番使われる箇所には最高品質の型を付ける」ことが大事かなと思います。どのアプリケーションでもそうだと思うんですが、アプリにはアプリ全体で使われている横断的な処理があると思います。例えばフォルシアが提供している検索アプリケーションだと、APIリクエストを受け取ってそれをSQL文に変換して、SQLのレスポンスを受け取って、それをJSONのAPIレスポンスに変換するというのが標準的な流れです。
今回私が触ったアプリケーションだと、リクエストパラメータからSQL文への変換の処理は、すべてのAPIをまたいで共通化されている処理でした。このような共通化された処理には最高品質の型を付けなければなりません。
なぜかというと間違った型を付けたり、質の低い型付けをしてしまうとバグの温床になったり、不要な型変換によってコードが見にくくなってしまったりするからです。よく言われるように、ほとんどのバグは一部のヤバい部分によって引き起こされます。頻繁に参照される箇所をこのようなヤバい部分にしてしまうのは、よくありません。
4つ目は逆説的なんですが、「リファクタリングとTypeScript移行を同時に行わない」ということです。TypeScript移行に関しては、対象となるファイルがアプリ全体で非常に広いので、リファクタリングとTypeScript移行を同時にやってしまうと、リグレッションテストが落ちたときに、その原因が移行時に意図せず混入したバグなのか、それともリファクタリングの影響なのか切り分けが非常に難しくなります。
またこちらのほうが大事なのですが、リファクタリングは始めるときりがなくなります。今回変更はアプリ全体に影響する可能性があるので、リファクタリングをし始めるとあれもこれも気になって、いつまでたってもTypeScript移行が終わらないという状況に陥ります。
リファクタリングは大事で、TypeScript移行がリファクタリングの大きなチャンスであることは間違いないんですが、同時にやるのではなくてリファクタリングをあとにやるのがよいのかなと思っています。まずはリファクタリングしたい気持ちをグッとこらえて、移行するときに「ここはリファクタリングができる」とコメントを残していきます。
そのとき、スニペットなどを活用してコメントのprefixを揃えると、あとから検索したり整理したりがしやすくなります。最後に移行が終わったあとで、コメントを刈り取るかたちでリファクタリングをすると、リファクタリングとTypeScriptへの移行が効率良くできるのではないかなと思います。
最後は「外部接続部分を型で縛る」ということです。先ほど紹介した検索のアプリだと、APIリクエストを受け取る部分、SQL文を投げる部分、SQLを受け取る部分、APIレスポンスを設定する部分の4点は自分で型を作成したり、型作成ツールを使ったりする必要がありました。このような外部接続部分は、いわば型の答え合わせです。
APIリクエストからSQL文への変換が自然に導出されるようにするのが大事かなと思います。またAPIのリクエストやレスポンスに関しては、Swaggerなどの型を自動的に生成するツールを使うのが非常に有効でした。
以上、5つを紹介しました。TypeScript移行は非常にコストも大きいですが、メリットもかなりあって、そのメリットはコストを上回ると今回の移行のプロジェクトを通して感じました。この発表が、みなさんにとってTypeScript移行の助けになれば幸いです。ご清聴ありがとうございました。
司会者:ありがとうございました。進め方を考えながら実際に案件に取り組んでいるのがすごくいいなと思いました。
質問が2件来ています。1つ目は「コメントのprefixはどんなものを使っていますか? 「FIXME」「TODO」ぐらいしか使ったことがないんですが」というものなんですが、いかがですか?
東川:そうですね。大事なのはこのTypeScript移行に伴うprefixであるということを示すことが大事かなと思っていて、私の場合だとfixme:TypeScript refactorableというprefixを付けていました。prefixにはいくつか種類があって、例えば引数が5つあるけど、後ろ2つは除けるというような場合や、変数の定義はされているんだけど、実際に後ろでは使っていない場合はremovableとかを付けていったかな。始めにスニペットをVS Codeのsnippets.jsonに定義して、そこから自動的に使っていました。
司会者:別の質問なんですが、「4番のリファクタリングを一緒にやらないについて、始めからそういう想定だったのか、それとも何か問題が起きてそういうふうにしようとしたのか、どっちなんでしょうか」。
東川:実は2番目と関係していて、本当にできるかトライアル移行で試したときにリファクタリングをしようかなと思ってリファクタリングを始めたら、あれもこれも気になってしまってできなくなってしまったという経験がありました。なので、リファクタリングをやめようという方針を決めて取り組みました。
司会者:素振りの重要性がわかりますね。
東川:はい。素振りはすごく有効でした。
司会者:ありがとうございます。もう1つ、「最高品質の型がどういうものか知りたい」という質問が来ています。
東川:曖昧な表現をしてしまって申し訳ないんですが、まずコードの品質を揃えることが重要かなと思います。共通化がされていてジェネリクスがきちんと使われているということが1つです。もう1つはType Assertionの数が少ないことかなと思います。
型の付け方がいびつだったりすると、途中でasなど不要なキャストを挟む必要があるので、そういったものの数が少なくなるのが品質の高い型なのかなと思います。ちょっと曖昧な表現をしてしまって恐縮なんですが、私が言いたいことは、一番使われる箇所は一番気合いを持って臨みましょうということです。
司会者:ありがとうございます。
関連タグ:
2025.01.16
社内プレゼンは時間のムダ パワポ資料のプロが重視する、「ペライチ資料」で意見を通すこと
2025.01.15
若手がごろごろ辞める会社で「給料を5万円アップ」するも効果なし… 従業員のモチベーションを上げるために必要なことは何か
2025.01.20
組織で評価されない「自分でやったほうが早い病」の人 マネジメント層に求められる「部下を動かす力」の鍛え方
2025.01.14
目標がなく悩む若手、育成を放棄する管理職… 社員をやる気にさせる「等級制度」を作るための第一歩
2025.01.09
マッキンゼーのマネージャーが「資料を作る前」に準備する すべてのアウトプットを支える論理的なフレームワーク
2025.01.14
コンサルが「理由は3つあります」と前置きする理由 マッキンゼー流、プレゼンの質を向上させる具体的Tips
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.01.21
言われたことしかやらないタイプの6つの言動 やらされ感が強く他人任せなメンバーを見極めるチェックリスト
2017.03.05
地面からつららが伸びる? 氷がもたらす不思議な現象
2015.11.24
人は食事をしないとどうなるか 餓死に至る3つのステップ
特別対談「伝える×伝える」 ~1on1で伝えること、伝わること~
2024.12.16 - 2024.12.16
安野たかひろ氏・AIプロジェクト「デジタル民主主義2030」立ち上げ会見
2025.01.16 - 2025.01.16
国際コーチング連盟認定のプロフェッショナルコーチ”あべき光司”先生新刊『リーダーのためのコーチングがイチからわかる本』発売記念【オンラインイベント】
2024.12.09 - 2024.12.09
NEXT Innovation Summit 2024 in Autumn特別提供コンテンツ
2024.12.24 - 2024.12.24
プレゼンが上手くなる!5つのポイント|話し方のプロ・資料のプロが解説【カエカ 千葉様】
2024.08.31 - 2024.08.31