Electron+Vite+React项目Drizzle/libSQL动态引入错误求助
解决Electron + Vite + Drizzle ORM集成SQLite的问题
核心前提:数据库操作必须放在主进程/预加载脚本
Electron渲染进程默认禁用Node.js API,直接在渲染进程调用SQLite驱动必然出问题,所有数据库逻辑要放在主进程,渲染进程通过IPC通信调用。
针对libSQL驱动的动态require错误
你之前的配置没生效,是因为dynamicRequireTargets没配置到主进程的Rollup构建规则里,根目录的build.commonjsOptions只作用于渲染进程,主进程的构建需要单独配置:
修改vite-config.ts中的electron插件配置:
import path from "node:path"; import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import electron from "vite-plugin-electron/simple"; import commonjs from "@rollup/plugin-commonjs"; export default defineConfig({ resolve: { extensions: [".js", ".jsx", ".ts", ".tsx"], alias: [ { find: "@components", replacement: path.resolve(__dirname, "src/renderer/components") } ] }, plugins: [ react(), electron({ main: { entry: "src/main/main.ts", // 给主进程单独配置构建规则 build: { rollupOptions: { external: ["@libsql/client"], // 排除Node.js原生模块,不打包 plugins: [ commonjs({ dynamicRequireTargets: [ "node_modules/@libsql/client/**/*", "@libsql/win32-x64-msvc" ] }) ] } } }, preload: { input: path.join(__dirname, "src/main/preload.ts") }, renderer: process.env.NODE_ENV === "test" ? undefined : {} }) ] });
同时移除根plugins里单独的commonjs()插件,避免冲突。
针对better-sqlite3的__filename错误
better-sqlite3依赖Node.js的__filename/__dirname全局变量,Vite构建主进程时默认不会注入,可通过两种方式解决:
方式1:配置Rollup插件
- 安装依赖:
npm install @rollup/plugin-node-resolve --save-dev
- 修改主进程的Rollup配置:
import nodeResolve from "@rollup/plugin-node-resolve"; // 在electron.main.build.rollupOptions.plugins中添加 nodeResolve({ preferBuiltins: true, browser: false }), commonjs({ dynamicRequireTargets: ["node_modules/better-sqlite3/**/*"] })
方式2:手动定义全局变量
在主进程入口文件顶部添加:
// src/main/main.ts import { fileURLToPath } from "node:url"; import { dirname } from "node:path"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); global.__filename = __filename; global.__dirname = __dirname;
通用正确流程示例
- 主进程编写数据库逻辑:
// src/main/db.ts import { drizzle } from "drizzle-orm/libsql"; import { createClient } from "@libsql/client"; import { ipcMain } from "electron"; const client = createClient({ url: "file:./local.db" }); export const db = drizzle(client); // 暴露IPC方法给渲染进程 ipcMain.handle("get-data", async () => { // 替换为你的数据库查询逻辑 return await db.select().from(yourTable); });
- 预加载脚本暴露IPC接口:
// src/main/preload.ts import { contextBridge, ipcRenderer } from "electron"; contextBridge.exposeInMainWorld("electronAPI", { getData: () => ipcRenderer.invoke("get-data") });
- 渲染进程调用:
// src/renderer/App.tsx const fetchData = async () => { const data = await window.electronAPI.getData(); console.log(data); };
内容的提问来源于stack exchange,提问作者GetReady
相关产品推荐
相关产品推荐

