|
| 1 | +# pnpm exec tsx を使用する決定 |
| 2 | + |
| 3 | +## 概要 |
| 4 | + |
| 5 | +Prisma seed スクリプト実行時に、従来の `pnpm dlx vite-node` から `pnpm exec tsx` への切り替えを実施しました。 |
| 6 | + |
| 7 | +## 背景:vite-node が非推奨となった理由 |
| 8 | + |
| 9 | +vite-node は本来、Nuxt 3 の SSR PoC として作成されました。その後、Vitest を実現させるための手段として機能していましたが、Vitest は Vite の公式なビルトイン Environment Module Runner に移行しました。 |
| 10 | + |
| 11 | +> "This project is firstly inspired by Nuxt 3's SSR implementation made by @pi0, as a PoC. Later, it made Vitest possible by providing the same pipeline as in Vite. It served the ecosystem well for a few years and later became a more generalized built-in solution as Vite Environment Module Runner. Vitest has migrated to the new official solution, which means vite-node has finished its mission. We will still keep it around for the ecosystem that built around it, but for new projects, please consider using the builtin Vite one instead." |
| 12 | +
|
| 13 | +**出典:** [vite-node GitHub Repository](https://github.com/vitest-dev/vitest) |
| 14 | + |
| 15 | +## 検討した代替手段 |
| 16 | + |
| 17 | +### 1. Node.js ビルトイン TypeScript サポート(`--experimental-transform-types`) |
| 18 | + |
| 19 | +**要件への適合度:** |
| 20 | + |
| 21 | +- ✅ 高速に動作(ネイティブ処理) |
| 22 | +- ✅ TypeScript をサポート |
| 23 | +- ✅ サードパーティツール不要 |
| 24 | + |
| 25 | +**実装:** |
| 26 | + |
| 27 | +```json |
| 28 | +"db:seed": "node --experimental-transform-types ./prisma/seed.ts" |
| 29 | +``` |
| 30 | + |
| 31 | +**トラブル:** |
| 32 | + |
| 33 | +```text |
| 34 | +Error [ERR_MODULE_NOT_FOUND]: Cannot find package '$lib' imported from /usr/src/app/src/lib/utils/contest.ts |
| 35 | +``` |
| 36 | + |
| 37 | +Node.js v22.17.0 ではビルトイン TypeScript サポートは存在しますが、`vite.config.ts` で定義されたエイリアス(`$lib` など)を解決できません。 |
| 38 | + |
| 39 | +**出典:** [Node.js TypeScript Support Documentation](https://nodejs.org/api/typescript.html#type-stripping) |
| 40 | + |
| 41 | +### 2. tsx(選定)✅ |
| 42 | + |
| 43 | +**要件への適合度:** |
| 44 | + |
| 45 | +- ✅ 高速に動作(v24.0.0 以降の Node.js より高速) |
| 46 | +- ✅ TypeScript をサポート |
| 47 | +- ⚠️ サードパーティツール(ただし既に依存パッケージから利用可能) |
| 48 | + |
| 49 | +**実装:** |
| 50 | + |
| 51 | +```json |
| 52 | +"db:seed": "pnpm exec tsx ./prisma/seed.ts" |
| 53 | +``` |
| 54 | + |
| 55 | +**利点:** |
| 56 | + |
| 57 | +- Vite の設定(エイリアス、resolve 設定など)を活用可能 |
| 58 | +- 既に `node_modules` 内に存在(peer dependency) |
| 59 | +- 実行速度が高速 |
| 60 | + |
| 61 | +**出典:** [tsx GitHub Repository](https://tsx.is/) |
| 62 | + |
| 63 | +## 決定理由 |
| 64 | + |
| 65 | +以下の理由から `pnpm exec tsx` を選定: |
| 66 | + |
| 67 | +1. Vite のエイリアス設定と互換性がある |
| 68 | +2. 既に依存パッケージから利用可能(追加インストール不要) |
| 69 | +3. 実行速度が高速 |
| 70 | +4. TypeScript サポートが完全 |
| 71 | + |
| 72 | +## Q&A |
| 73 | + |
| 74 | +### Q1: なぜ `pnpm exec` を使うのか(`pnpm dlx` との違い) |
| 75 | + |
| 76 | +**A:** `pnpm dlx` は毎回最新版をレジストリからダウンロードして実行するため、オーバーヘッドが大きいです。一方、`pnpm exec` は `node_modules/.bin/` にインストール済みのバージョンを実行するため、高速です。 |
| 77 | + |
| 78 | +```bash |
| 79 | +# 毎回最新版をダウンロード(遅い) |
| 80 | +pnpm dlx vite-node ./prisma/seed.ts |
| 81 | + |
| 82 | +# インストール済みバージョンを実行(高速) |
| 83 | +pnpm exec tsx ./prisma/seed.ts |
| 84 | +``` |
| 85 | + |
| 86 | +**出典:** [pnpm CLI Documentation](https://pnpm.io/cli/dlx) |
| 87 | + |
| 88 | +### Q2: tsx が既にインストール済みである理由 |
| 89 | + |
| 90 | +**A:** tsx は明示的にインストールしていないにもかかわらず、動作します。これは以下の依存パッケージが peer dependency として tsx を指定しているため: |
| 91 | + |
| 92 | +- `@mermaid-js/mermaid-cli` → `postcss-load-config` → `tsx 4.19.2 (peer)` |
| 93 | +- `@testing-library/svelte` → `vite` → `tsx 4.19.2 (peer)` |
| 94 | +- `vitest` → ... → `tsx 4.19.2 (peer)` |
| 95 | + |
| 96 | +pnpm は peer dependency を自動的にインストール・管理するため、明示的なインストールなしに利用可能です。 |
| 97 | + |
| 98 | +**出典:** [pnpm Peer Dependencies Resolution](https://pnpm.io/how-peers-are-resolved) |
| 99 | + |
| 100 | +### Q3: Node.js ネイティブの `--experimental-transform-types` ではダメな理由 |
| 101 | + |
| 102 | +**A:** Node.js ネイティブの TypeScript サポートは、型情報を削除するのみで、Vite のビルドツール機能(モジュール解決、エイリアス、ローダーなど)を提供しません。 |
| 103 | + |
| 104 | +本プロジェクトの `seed.ts` では以下が必要です: |
| 105 | + |
| 106 | +- **Vite のエイリアス:** `$lib` → `src/lib` |
| 107 | +- **ディレクトリインポート:** `./.fabbrica` → `./.fabbrica/index.ts` |
| 108 | +- **相対パス解決:** `../src/lib/types/task` |
| 109 | + |
| 110 | +Node.js 単体ではこれらを解決できないため、Vite 互換のツール(tsx など)が必要です。 |
| 111 | + |
| 112 | +**出典:** |
| 113 | + |
| 114 | +- [Node.js TypeScript Type Stripping](https://nodejs.org/api/typescript.html#type-stripping) |
| 115 | +- [Vite Config Reference](https://vite.dev/config/) |
| 116 | + |
| 117 | +## 実装内容 |
| 118 | + |
| 119 | +### package.json の変更 |
| 120 | + |
| 121 | +```json |
| 122 | +{ |
| 123 | + "scripts": { |
| 124 | + "db:seed": "pnpm exec tsx ./prisma/seed.ts" |
| 125 | + } |
| 126 | +} |
| 127 | +``` |
| 128 | + |
| 129 | +### 実行方法 |
| 130 | + |
| 131 | +```bash |
| 132 | +pnpm db:seed |
| 133 | +``` |
| 134 | + |
| 135 | +## 参考資料 |
| 136 | + |
| 137 | +- [vite-node](https://github.com/vitest-dev/vitest) |
| 138 | +- [tsx](https://tsx.is/) |
| 139 | +- [pnpm CLI](https://pnpm.io/cli) |
| 140 | +- [Node.js TypeScript](https://nodejs.org/api/typescript.html) |
| 141 | +- [Vite Configuration](https://vite.dev/config/) |
0 commit comments