Svellte/SvelteKit tips集
問題
import { PrismaClient } from "@prisma/client"
export const prisma = new PrismaClient()
こんな感じにフツーにPrismaClientを定義して、
Prisma & SvelteKitをadapter-node
でbuildして動かそうとすると
ReferenceError: __dirname is not defined in ES module scope
エラーが出る。
解決策
requireを用いてimportする。
ただし、普通にrequireするだけでは型補完が効かなくなるので、少々Hackyな方法で定義する。
Github Issue Comment参照
import type { PrismaClient as ImportedPrismaClient } from '@prisma/client';
import { createRequire } from 'module';
const require = createRequire(import.meta.url ?? __filename);
const { PrismaClient: RequiredPrismaClient } = require('@prisma/client');
const _PrismaClient: typeof ImportedPrismaClient = RequiredPrismaClient;
export class PrismaClient extends _PrismaClient {}
import { PrismaClient } from './prisma';
export const db = new PrismaClient();
なぜ起きるか
__dirname や __filename は、CommonJSで定義されているが、ESMでは定義されていない。
SvelteKitでは基本的にESMなため、Conflictする。
(ちなみにSolidStartとかでもこの問題は起きるっぽい)
Issueに興味深いコメントあり
As you are likely aware, the root cause seems to be that we're using ES2022 but the Prisma client is using an old __dirname() function that isn't support/available in ES2022, which I believe is the default used in SvelteKit. The reason for the continued use of this __dirname() function for the detection of the environment specifically for Vercel hosted websites.
ご存知のように、根本的な原因は、ES2022を使っているのに、PrismaクライアントがES2022ではサポート/利用できない古い__dirname()関数を使っていることにあるようです(これはSvelteKitで使われているデフォルトだと思います)。この__dirname()関数を使い続けている理由は、VercelがホストするWebサイトに特化した環境の検出のためです。
だからかー。Vercelに上げてる人が多いからみんなハマってないのか。ぐぬぬぬぬ
問題
NeovimのSvelte LSPがjs/tsの変更を検知してくれない
解決策
nvim-lspconfigを使っているなら以下の設定を入れよう
lspconfig.svelte.setup{
on_attach = function(client, bufnr)
vim.api.nvim_create_autocmd("BufWritePost", {
pattern = { "*.js", "*.ts" },
callback = function(ctx)
-- Here use ctx.match instead of ctx.file
client.notify("$/onDidChangeTsOrJsFile", { uri = ctx.match })
end,
})
end,
}
原因
didChangeWatchedFiles
ではなく、$/onDidChangeTsOrJsFile
なる名前でnotificationを受けているらしい
なので、autocmd
を使ってプロジェクト内のjs
、ts
ファイルの変更を監視して、変更のたびにLSPの$/onDidChangeTsOrJsFile
へ通知を送る実装をマニュアルで書かないといけない
流石に解決されるのは時間の問題かもしれないが。。。
あと新しいファイルも検知できてない
現在直してもらってる
Inlay hintsをNeovimで有効にする
Neovim 0.10.0でInlay hintsに対応
Svelte language serverも対応しているので
lspconfig.svelte.setup{
on_attach = function(client, _)
local root_dir = client.config.root_dir
vim.api.nvim_create_autocmd("BufWritePost", {
pattern = {
root_dir .. "/*.js",
root_dir .. "/*.ts",
},
callback = function(ctx)
client.notify("$/onDidChangeTsOrJsFile", { uri = ctx.file })
end,
})
end,
settings = {
typescript = {
inlayHints = {
parameterTypes = { enabled = true },
enumMemberValues = { enabled = true },
parameterNames = {
suppressWhenArgumentMatchesName = true,
enabled = "literals", -- 'none' | 'literals' | 'all';
},
functionLikeReturnTypes = { enabled = true },
variableTypes = { enabled = true },
},
},
}
これでうごきます。
ここら辺に色々書いてあります
Inspectorが使いたい
VSCodeで使えるInspectorをvim/neovimで使えるようにした
svelteのhtml要素のevent型を簡単に取り出せるやつ作った