正式タイトル
Typescript使ってるNext.jsでtsconfigにbaseUrl: "."してる状態でVitest使いたいけど、srcディレクトリを作りたくないし@とか付けたくない。
どゆこと
create-next-app --tsコマンドで作成したNextjsアプリのtsconfig.jsonにbaseUrl: "."を追加すると、
import { Foo } from "../components/Foo"
とするときに
import { Foo } from "components/Foo"
と書けます。
baseUrlで指定したパスからの相対パスで指定できるようになるわけです。
で、突貫で作ったNextjsアプリに後からVitestを足そうとかした時にあるやつなんですが、既にtsconfigにそう書いてある状態で後から
「これまでテスト書かずに来たけど、真面目にやるならテスト書いてないのはアレだし書くか」
となったときに掲題の問題が生じます。
初期ならsrcを足して解決してもいいですが、ある程度成熟している状態の場合は全部そうするのは面倒よねって感じになるわけです。
Vitestは当然、components/Fooなんて書いても${pwd}/components/Fooなんてないよと判断するのでVitestにこれを解釈させる必要があります。
これを解釈させるためには{vitest|vite}.config.tsresolve.aliasを以下みたいな感じで設定する必要があります。
//...importとか
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
},
resolve: {
alias: {
"@": path.join(__dirname, 'src/'),
},
},
})
こうすると、src/components/Fooとなっている所で../components/Fooとしている場合に@/components/Fooとできるようになります。
ただこれ、当然ですが"": path.join(__dirname, './'),なんて指定はできないので、components/Fooはどうするべという問題があります。
これの解決策は2つ。
なんとなくいけてない気がするけど正道的な解決法を取るか、依存関係を増やすかです。
なんとなくいけてない気がする解決法
個人的になんとなくイマイチな気がしますが、pageとappとcomponentsを一つずつaliasに指定するという方法です。
イマイチとか言いましたが、正道的な解決法としてはこちらな気がします。
//...importとか
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
},
resolve: {
alias: {
"page": path.join(__dirname, 'page/'),
"app": path.join(__dirname, 'app/'),
"components": path.join(__dirname, 'components/'),
},
},
})
場合によっては、styles/やlib/, util/なんかも足しましょう。
手間ですがたかが3行ですし、普通はこれらと上記のディレクトリ以外にファイルを突っ込む人はいないです。
ただし、tsconfig.jsonのbaseUrlを変更するとなったときに非常に面倒なことになります。
……いやまあ、tsconfig.jsonのbaseUrlを変更するとなった時点でVitest抜きに色々大変なので、考慮する必要はないのかもしれませんが。
依存関係を増やす解決法
baseUrlの値を読んで解決してくれるvite-tsconfig-pathsというプラグインが存在します。
これを使用すれば一つずつ追加する必要はなくなります。
/// <reference types="vitest" />
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
plugins: [react(), tsconfigPaths()],
test: {
environment: 'jsdom',
},
})
ただし、当然ですが依存関係が増えます。
不要な依存関係は増やさないことがベストなので、便利ですがバッドな選択肢かもしれません。便利ですが。
終わりに
当然ですが、不要なライブラリを使用することは避けるべきなので手動でaliasを設定する方が良いと思います。
良いと思いますが、まあそれはそれとして便利な方がいいよねという気持ちが存在することも事実です。
その辺は、まあ自分の心とかチームの空気感とかで決めましょう。