遅ればせながらPrismaを使ってみたのですが、seed.tsで生成された型情報を使おうとしてドハマリしたのでメモ書き。
タイトルがアホみたいに長いのは、同じ問題でハマっている人が検索でヒットしやすければよいと思った弊害です。
Schema.prisma と Seed.ts
以下のようなモデルの定義を行いました。
model User {
id Int @id @default(autoincrement())
first_name String
last_name String
first_name_kana String
last_name_kana String
created_at DateTime @default(now())
updated_at DateTime @updatedAt
deleted_at DateTime? // 削除日時
}
その後、npx prisma migrate dev --name init
で初期テーブルを作成、
npx prisma generate
で型情報の生成を行いました。
ここまでは問題なし。
次に以下の様にseed.tsを作成しました。
import { User, PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function createUsers(): Promise<User[]> {
const userData = [
{
id: 1,
first_name: 'アカウント',
last_name: '管理',
first_name_kana: 'あかうんと',
last_name_kana: 'かんり',
}
]
const results: User[] = []
for (const user of userData) {
results.push(await prisma.user.upsert({
where: { id: user.id },
update: {},
create: user,
}))
}
return results
}
async function main() {
console.info('create user data')
const createdUsers = await createUsers()
console.log(createdUsers)
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
VSCode上でも特にエラー表示等もなく、これも問題なさそう。
package.json
には以下の通りに設定を行いました。
// ...追加部分
"prisma": {
"seed": "ts-node prisma/seed.ts"
},
//...
エラー
これでnpx prisma db seed
を実行すると、
SyntaxError: Named export 'User' not found. The requested module '@prisma/client' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from '@prisma/client';
const { User } = pkg;
うん、?
@prisma/client
モジュールがCommonJS
モジュールであり、ESモジュールとしての名前付きエクスポートをサポートしていないうんぬん。
言われた通りの分割宣言や、エラー文言で検索して出てきたseedコマンドの実行オプションに--compiler-options {\"module\":\"CommonJS\"}
を追加する方法でもうまくいかない。
seed.tsで型情報をつかわないでanyにしておけば普通に動くんだけど、いまいちスッキリしない。
(こういうことに拘っちゃうのありますよねぇ)
解決方法: ts-node
を使わない
まずはts-nodeをクビにします。
npm uninstall ts-node
その後、tsx
を新規で採用します。
npm install --save-dev tsx
package.jsonも修正。
// ...修正
"prisma": {
"seed": "tsx prisma/seed.ts"
},
// ...
これで無事、型情報を使用しつつ、npx prisma db seed
が実行できました。
ts-node
, tsx
って何
tsx
と聞くとReactのJSXを連想すると思いますが、全然関係ない罠です。
どちらも、TypeScriptのコードをNodeで直接実行するためのツールになります。
いろいろ調べるとts-node
の更新は止まっているようで、最近はtsx
を利用するのが主流だそう。
今回問題になったのは、CommonJS
とECMAScript Module
の環境?差異にあって、ts-code
はCommonJS
とECMAScript Module
の混在環境では動いてくれないことが多く、tsx
はだいたい動いてくれるという状態だそうです。
これで3時間くらいハマりました。