ESModulesのインポートパス
個人的には好んで相対パスを使う。
バリエーション
相対パスを使う方法
絶対パス(プロジェクトルートからの相対パスや相当物)を使う方法
主要な関心にエイリアスを貼って使う方法
これは強い意思で絶対にやらない。コード解析の面倒ごとを増やすだけ
ディレクトリ設計の前提
関連が強いものはより近くにあるようにディレクトリがわかれている
近いものは相対パスで表現しやすく、遠いものは多くのディレクトリを遡る必要がある
遠いものに絶対パスがほしくなるようになる
sharedのコンポーネント、みたいな存在だけ少し悩ましくなる
絶対パスが欲しいと言われたとき、自分はこう提案する
相対パスとルートからの絶対パスを共存させるのはどうか
近いものは相対パスで記述する
*.test.ts *.stories.tsx みたいなものもこれがうれしい
次のような道具があったときに互いに相対参照したい
code:plaintext
someFeature/
Provider.tsx
Context.ts
useFeature.ts
index.ts
遠いものは絶対パスで記述すると簡便になる
あるいは「なってしまう」。遠いものは異様に見えてほしい
code:typescript
// in src/features/foo/Main.tsx
import React from "react";
import SomeComponent from "./SomeComponent"; // src/features/foo/SomeComponent.tsx
import Tab from "src/components/Tab";
import SomeModal from "src/modals/SomeModal";
import useRerender from "src/utils/useRerender";
もしやるなら自動で書き分けたい
VSCodeでは typescript.preferences.importModuleSpecifier を shortest にするとだいたい良い感じかも
src直下のディレクトリを跨ぐ場合は絶対パス、みたいなESLintルールは結構簡単に書けそう
親方向に遡るインポートが発生する時点でディレクトリ構成を間違ってると言える
絶対パス(プロジェクト相対パス)を使いたい理由として聞いてきたものとリアクション
../../../ がつらい
めちゃめちゃわかる、けど要注意
ディレクトリ設計の失敗という臭いものに蓋をしているかもしれない
遡る必要があるものは十分に関心が遠いもののときなはず
それがアプリケーション内で一級市民であるというとき、たしかに絶対パスが書けると嬉しそう
ファイルをコピーするとおかしくなる
1. 疑問:ファイルのコピーがそもそも不適切ではないか
共通化しろと言っているのではない。DRYの典型的な誤りを犯す必要はない
一方で定番の道具が並んでいるものをコピーしてきたい事情は理解する
個人的にはディレクトリの移動を挟むコピーはしないが……
2. 確認:コピーしても問題ないはずではないか
頻出の道具は絶対パスで記述される程度に遠い存在になるので、絶対パスにならないか
shortestの挙動が文字列長最小だったら困るかもだけど、そうなんだっけ
ルートに近いところでコピーが起こると相対パスの方が短い判定になるかも?
どこから見てもどのファイルを見ているか自明になる
同意はするが副作用がある
近いファイルをインポートするのに近くにあるように見えない
遠い(=関係の弱い)ファイルを違和感なくインポートできてしまう
とくに遠いファイルのパッケージ内に閉じた道具をいきなりインポートしかねない
レビューで頑張るのは絶対無理なのでおすすめしないが、別の道具でカバーできる可能性はある
最終的には書く人たちが納得していればなんでもよい
共存を許容したうえで良い感じに全部自動整形してくれるESLintルールがあったら何も問題なさそう
全部絶対パスにするのは結構強めに反対で、相対パスにも良さがある
いろいろエイリアスを貼りまくるのはとにかくお勧めしない
静的解析時に設定が散らばりまくることになる
TSの新しい構文のサポートが済むまで時間がかかるのと同じことが起こる