見出し画像

既存プロダクトにTypeScriptを導入した話

こんにちは、スペースマーケットのフロントエンドエンジニアの荒田です。

今回は既存プロダクトにTypeScriptを導入した手順と、その学びをご紹介したいと思います。

やる前に意識したこと

flow時代の型は一旦コメントアウトする

弊社ではflowによる運用を続けてきましたが、そこまで厳密に型を定義していたわけではなく、いくつかの箇所でObject や Functionが散見されていたため、あくまで参考程度にコメントアウトしておくことにしました。

TypeScriptや導入について学ぶ

そもそも私はTypeScriptがflow-typeの親戚ぐらいの認識だったので、まず弊社と同じ技術スタックでTypeScriptを導入している記事をいくつか調査して導入手順やTypeScriptについて理解することにしました。事前調査のおかげでその後の導入がスムーズになり、TypeScriptについてもある程度学べたのでよかったです。


TypeScript導入に伴って変更(or 削除)が必要だったもの

* flow-type
* storybook
* jest
* babel

やったこと

flowの削除

TypeScriptを導入するにあたりflow及びflowに関連したモジュールを削除しました。

$ yarn remove flow flow-typed @babel/preset-flow @babel/plugin-transform-flow-strip-types eslint-plugin-flowtype

全ての.js | .jsxファイルから// @flowを削除しました。

TypeScriptの導入

$ yarn add -D typescript  

@babel/preset-typescriptを使ってTypeScriptを変換する

弊社では既にbabelを使っており、影響を最小限にするためtscでのbuildではなくbabel(@babel/preset-typescript)を選択しました。

.babelrc

{
 "presets": ["@babel/preset-react", "@babel/preset-env", "@babel/typescript"],
 ...
}

TypeScript化する際にパスの認識をしてくれなかったため、追加でmodule-resolverのaliasにパスを定義しました。

{
   "plugins":  [
     "module-resolver",
     {
       "alias": {
         "components": "./src/components",
         "config": "./src/config"
       },
       "extentions": [".ts", ".tsx"]
     },
     "typescript"
   ],
}

prettier, eslintの設定

TypeScript化するにあたってprettierとeslintが効かなくなっていたため、追加でいくつか設定をしました。

$ yarn add -D @typescript-eslint 

.eslintrc

{
 ...
 "plugins": ["@typescript-eslint"],
 ...
}

StorybookのTypeScriptサポート

StorybookのwebpackでTypeScriptを動かすためにts-loaderを導入しました。

$yarn add -D ts-loader

.storybook/webpack.config.js

module.exports = ({ config }) => {
 config.module.rules.unshift({
   test: /\.(ts|tsx)$/,
   use: ['ts-loader'],
 })
}

既存の設定だとjsxファイルしか認識しないため.tsxを正規表現に追加。

.storybook/config.js

const req = require.context('../src/', true, /.stories.jsx?$/)
↓
const req = require.context('../src/', true, /.stories.(jsx|tsx)?$/)

ts-jestの導入

jestをTypeScriptに対応するためts-jestを導入しました。

$ yarn add -D ts-jest

jest.config.js

{
 "jest": {
   "moduleFileExtensions": ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
   "transform": {
     "^.+\\.ts$": "ts-jest"
   },
 }
}

導入作業は以上になります。


学んだこと

全てやりきらない。
全てのファイルを.jsxから.tsxに移行するのは現実的に時間がかかりすぎてしまいます。やるべきことのスコープを最低限開発できる状態にすることが重要だと思いました。
PRは最小単位にする。
影響範囲を最小限に抑え、レビュー及びリリースしやすいPRを作成することが大切だと実感しました。常々気をつけているつもりでしたが、開発環境のマイグレーションなどは変更差分が多く巨大PRになってしまいがちなので改めてPRの切り分けは気をつけたいと思いました。

TypeScriptの導入の知見を得られたことに加え、特に私にとって大切な学びとなったのは上記の二つでした。

最後に


スペースマーケットでは、機能開発はもちろん、技術領域に係る意思決定から仕様、運用方法の策定など積極的・主体的に関わりたいエンジニアを募集中ですので、興味がありましたら募集要項を御覧ください!

そして私の愛すべき地元、千葉県松戸市に素敵なスペースが続々と増えていることに感動&感謝し、それらのスペースをまとめてみました。
お近くにお立ちよりの際にはぜひ利用してみてください!!




この記事が気に入ったらサポートをしてみませんか?