You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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插件

  1. 安装依赖:
npm install @rollup/plugin-node-resolve --save-dev
  1. 修改主进程的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;

通用正确流程示例

  1. 主进程编写数据库逻辑:
// 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);
});
  1. 预加载脚本暴露IPC接口:
// src/main/preload.ts
import { contextBridge, ipcRenderer } from "electron";

contextBridge.exposeInMainWorld("electronAPI", {
  getData: () => ipcRenderer.invoke("get-data")
});
  1. 渲染进程调用:
// src/renderer/App.tsx
const fetchData = async () => {
  const data = await window.electronAPI.getData();
  console.log(data);
};

内容的提问来源于stack exchange,提问作者GetReady

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:43:11