TypeScript で絶対パスの import をやめた話

こんにちは。亀山です。

趣味で作っている比較的大きなコードベースの Web アプリで最近やったことを紹介します。

いままで TypeScript の import は相対パスではなく絶対パスで記述するようにしていました。相対パスでは import "../../../common/model/foo" のようにものすごく長い文になることや、import する側のファイルを移動するときにパスを修正しないといけないことなどから、絶対パスを使っていました。

絶対パスで記述するには tsconfig.json の paths を使います。次のような設定によって、先程の import 文は import "model/foo" のように書き直せます。また、マッピングの指定によっては import "@common/model/foo" のように書けてカッコいいです。

"paths": {
  "*": ["*", "src/*", "src/main/*", "src/common/*"]
},

しかし、開発環境を VSCode にしてから、import 文を手作業で頑張るのはやめようと考えるようになりました。 VSCode 上でファイルを移動すると自動的に import のパスを修正してくれるので、手作業で修正する必要がなくなったこと、保存時の organizeImports を有効にすれば並びも自動的に整理されて見栄えも悪くないこと、またその設定を workspace などで他の人にもスムーズにシェアできることから、相対パスの問題が解決され、逆に人間の手を加えないほうが良いと考えます。 今の workspace の設定は次のようにしています。

"typescript.preferences.importModuleSpecifier": "relative",
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
  "editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
  "source.organizeImports": true
}

paths を指定すると Jest の moduleNameMapper を書かないといけなかったり、同じファイルを示すのに複数の書き方が存在したり、VSCode のパスの自動修正がたまに効かないといった問題がありました。moduleNameMapper の問題は、かつては拙作の tsconfig-paths-jest、今では ts-jest/utils の pathsToModuleNameMapper によってある程度簡単に解決できるのですが、なるべく設定項目は減らしたいし、コンパイラとの格闘は避けたいです。

VSCode で開発環境の設定を揃えられることによって、心配事が減ってコーディングに集中できて嬉しいですね。以上、小ネタでした。