投稿目的
- よりよい方法をご教授いただきたい
- 現場での対応の備忘録
本題
きっかけ
上長「import
文を書く際、絶対パスでpath
を記載するようにしましょう」
現場ぼく「承知いたしました(`・ω・´)ゞ」
src
配下のファイル同士でimport
をする際、src
ディレクトリを基準としたパスでimport
文のpath
を記述したいです。
下記のようなディレクトリ構成だとすると、Page.tsx
内でType.d.ts
にて定義されたtype Example
を使用したい場合、下記のような感じで記述したい、というイメージです。
とにかく、相対パス("../types/Type"
)でのpath
記述をやめたい、とご理解ください。
import { Example } from "types/Type";
root
|
├── public
├── src
| ├── pages
| | └─ Page.tsx
| └── types
| └─ Type.d.ts
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.node.json
└── vite.config.ts
環境について
TypeScript
×React
×vite
のプロジェクトです。
主なパッケージ、バージョン、コマンドは以下のようになっているものとします。
{
"scripts": {
"dev": "npm run build && vite --host",
"build": "tsc -b && npm run format && vite build",
"format": "prettier --write src/**/*.{js,ts,jsx,tsx} && npm run lint",
"lint": "eslint .",
...
},
"dependencies": {
"react": "^18.3.1",
...
},
"devDependencies": {
"typescript": "~5.6.2",
"typescript-eslint": "^8.11.0",
"vite": "^5.4.10"
...
}
}
今回は、tsconfig.json
では具体的な設定を書かず、アプリケーションの設定はtsconfig.app.json
に記述するものとします。
{
"files": [],
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
}
alias
を設定してpath
を記載するようにしてみる
tsconfig.json
にcompilerOptions.baseUrl
を設定することによって、TypeScript
がimport
したいモジュールを探す際に基準となるディレクトリを設定することができます。
また「相対パスを使わずに書いているよ~」ということを分かってもらうために「@src
」というprefixをimport
時のpath
に記載しようと思い、compilerOptions.paths
を設定しました。
今回の場合、baseUrl
が/src
、paths
内の@src/*
は/src/*
、つまりsrc
ディレクトリを指すようなaliasとして設定されました。
よって、下記のようにimport
文を記述できます。
import { Example } from "@src/types/Type";
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"@src/*": ["*"]
},
...
},
...
}
各ファイルのimport
文の記載を更新してみると、エラーがなくなり期待通りimport
できるようになりました!
push
してプルリク作るぞ~と思いnpm run build
(ビルドコマンド)を実行すると、ESLint
のエラーチェックは通過して、下記のようなvite
のエラーが発生しました。
どうやら、ビルド時にimport
文が正しく解釈されていないようです...
vite v5.4.10 building for production...
✓ 3 modules transformed.
x Build failed in 48ms
error during build:
[vite]: Rollup failed to resolve import "@src/page/Page" from "/home/USERNAME/PROJECT_NAME/src/main.tsx".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
TypeScript
のコンパイルに関する設定はいじってきましたが、ビルドを実行するvite
側の設定はいじっていませんでした。
下記の設定を追加します。
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
export default defineConfig({
plugins: [react()],
// 下記を追加
resolve: { alias: [{ find: "@src", replacement: "/src" }] }
});
@src
というaliasは/src
に置換してくれ、とvite
に設定します。
この状態でnpm run build
してみると、ビルドが成功しました!!
aliasいらなくね?
無事プルリクを作成できましたが、コメントをいただきました。
上長「@src
のprefixいらなくない?」
ぼく「...」
すみません、勝手に設定してしまいました。
ということで、下記のようにimport
文を記載できるように修正します。
import { Example } from "types/Type";
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"/*": ["src/*"]
},
...
}
先ほどpaths
内のkey
に設定していた@src/*
を/*
に変換しただけです。
vite.config.ts
に設定していたresolve.alias
を削除して... あれ、ビルドがうまくいかないな...
ここから泥沼にはまってしまいました...
vite v5.4.10 building for production...
✓ 3 modules transformed.
x Build failed in 48ms
error during build:
[vite]: Rollup failed to resolve import "page/Page" from "/home/USERNAME/PROJECT_NAME/src/main.tsx".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
解決策 vite-tsconfig-paths
上長「vite-tsconfig-paths
を使うといいと思うよ」
ぼく「神ですね」
$ npm i -D vite-tsconfig-paths@latest
{
...
"devDependencies": {
"vite-tsconfig-paths": "^5.1.4",
...
},
...
}
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
// tsconfigPaths()を追加
plugins: [react(), tsconfigPaths()]
});
vite-tsconfig-paths
はvite
にimport
解決能力を授けてくれるパッケージのようです。
このパッケージを用いることで、vite
がいい感じにimport
文を解釈してくれるようになり、無事プルリクもマージされましたとさ。
import { Example } from "types/Type";
最後に
いろいろ大変でしたが、vite-tsconfig-paths
のお陰で一件落着しました、便利なパッケージに感謝です。
vite.config.ts
やtsconfig.json
など、環境周りは敬遠してきてしまっていたことを後悔です...
他にも良い方法があったり、vite.config.ts
tsconfig.json
などのおすすめ設定があったりしたら、コメントいただけますと幸いです!