stand.fmのTypeScriptへの移行と活用株式会社stand.fm エンジニア 外松 俊尚2021/11/10 TECH STAND #6 TypeScript
View Slide
外松 俊尚 stand.fm エンジニア React NativeやNode.jsでプロダクト開発 愛媛からフルリモート @toshi__toma
stand.fmは誰でもかんたんに アプリで収録・LIVE配信ができる音声プラットフォーム
いまの stand.fm プロジェクト● アプリ、Web、サーバーサイド全てJavaScript○ React Native, React(React Native for Web), Node.js○ メインはFlow、一部はTypeScript● Monorepo (npm パッケージ)● プロジェクトごとにTypeScriptへの移行を開始○ 新しくプロジェクトを作る時はTypeScript
TypeScriptへの移行
TypeScript移行のモチベーション● ライブラリの型定義● TypeScriptが得意なメンバーが増えた印象● 標準の組み込み関数の型推論● Monorepo内で依存してるパッケージの型定義● 開発体験● etc
移行の調査● 定期的にFlow辛い・TypeScript移行するのどうだろって話はあったけど、なかなか進まなかった○ どれくらい大変なのか分からない○ 実際何が必要なのか分からない● 3日間という期間を決めて調査してみた
移行の調査● 一番難しそうなプロジェクト(アプリとメインのapiサーバー)で実験○ お試しで移行作業してみたり、必要なタスクを整理してドキュメントにまとめる● Flowでの型定義はある程度ちゃんと書いてあったので、比較的スムーズにできそう(strict: true)● ある程度やることの見通しがたったので、移行を開始
flow to TypeScript1. 周辺ツールやビルド設定2. flowtsでTSに変換3. 型エラーを修正● 検討した移行ツール○ flowts: https://github.com/zxbodya/flowts○ flow-to-ts: https://github.com/Khan/flow-to-ts
型エラーリストの作成● メインは型エラーの対応● どんな種類の型エラーがどれくらいでるのか?● tscのデフォルトの出力だと厳しい
型エラーリストの作成● @aivenio/tsc-output-parser○ tscの出力をJSON形式に○ https://github.com/aiven/tsc-output-parser● JSONを集計○ ファイル単位のエラー数○ エラーの種類ごとの数● どんな種類のエラーがどれくらいでるのか見通しがたった
Typeカバレッジ● FlowからTypeScriptへ移行して型付けのカバレッジがどうなるか気になった● 型推論される箇所が増えそうなイメージはあった
Typeカバレッジ● カバレッジの変化を確認○ flow-coverage-report■ https://github.com/rpl/flow-coverage-report○ typescript-coverage-report■ https://github.com/alexcanessa/typescript-coverage-report● flowtsでTS化するだけでカバレッジが上がった○ 最大で30%ほど上がったプロジェクトがあった
TypeScriptの活用
ライブラリの型定義● Flow Project: ライブラリの型定義が用意されてない場合○ any or TypeScriptの型定義からFlowの型定義に変換(flowgen)○ 不完全 & 追従が手間● TS Project: ライブラリ本体で型定義が用意されてない場合はDefinitelyTypedからインストール● 移行時: 足りない@typesパッケージをまとめてインストール
ライブラリの型定義ファイルのバージョン● typesync○ packge.jsonのtypes, typingsが無い & @types/packageがある パッケージをインストール● インストールするバージョン○ typesyncはライブラリ本体のパッケージのsemverを尊重○ もちろん、semverが揃ってないものもある■ 個別に型定義ファイルのヘッダーをチェックしたり■ 可能な限り対応するバージョンは揃えた
Monorepo内での依存とビルド● Flow Project: Babelでビルド○ build時は依存しているパッケージもビルドが必要● 依存関係を管理○ ビルドコマンドに依存するプロジェクトのビルドを追加■ 全部ビルドするのにも時間がかかる○ 新しく依存するプロジェクトが増えた時にもれやすい
Project References● Project Referencesを活用○ references: [], composite: true, declaration: true● tsc --buildで依存しているプロジェクトも含めて適切な順番でビルド(incremental build)● Babelのままだと使えないので、TS化のタイミングでビルドをtscに移行
Monorepo内のパッケージの型定義● Flow Project: 依存してるプロジェクトの型定義はanyだった● --declaration○ ビルド時に型定義ファイルを出力● package.json > typings or typesを設定● より型安全になった
エラーハンドリング● 関数で発生しうるエラーも型で宣言して適切にハンドリングしたい● Either型○ type Either = | Right>○ 成功時・失敗時の型を表現● 特に異常系が発生しやすい層では、Either型を返すように○ DBアクセスなど
Either型● fp-ts: https://github.com/gcanti/fp-ts○ TSで関数型プログラミング○ isRight, isLeft, tryCatch, etc
まとめ● stand.fmはFlowからTypeScriptへの移行中● 移行は始まったばかりなので、やることは大量にある● TypeScriptの機能を活用して、開発体験や型安全性を高めていきたい
We are hiring!エンジニア積極的に募集中ですhttps://corp.stand.fm/recruit詳細はこちら ● CTO候補● VPoE候補● クライアントエンジニア● バックエンドエンジニア● 機械学習エンジニア● 配信基盤エンジニア● QAエンジニア● エンジニアリングマネージャー● UI/UXデザイナー積極募集しているプロダクト開発メンバー