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

Electron中正确导入Node模块:集成lmdb库报错求助

Electron集成lmdb库报错:Uncaught TypeError: open is not a function

我是Electron新手,正尝试在Electron中集成npm的lmdb库,但操作方式可能有误,特此求助。我使用preload.js、main.js和renderer.js,相关代码如下:

现有代码

preload.js

const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('versions', {
    node: () => process.versions.node,
    chrome: () => process.versions.chrome,
    electron: () => process.versions.electron,
    lmdb: () => process.lmdb
    // we can also expose variables, not just functions
})

main.js

const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
    const win = new BrowserWindow({
        width: 1200,
        height: 800,
        autoHideMenuBar: true,
        // resizable: false,
        icon: path.join(__dirname, 'gigatreelogosvv.ico'),
        // autoHideMenuBar: true,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            nodeIntegration: true,
            contextIsolation: true
        }
    })

    win.loadFile('index.html')
    win.webContents.openDevTools()

}

renderer.js

const open = versions.lmdb.open;
let blocks = open({
    path: "./db/blocks",
    compression: true,
});

控制台报错信息

Uncaught TypeError: open is not a function
    at renderer.js:8:14

问题原因

  1. preload.js暴露逻辑错误:你写的lmdb: () => process.lmdb里,process对象根本不存在lmdb属性,而且这里暴露的是一个函数,不是lmdb模块本身。渲染进程中versions.lmdb是函数而非包含open方法的对象,自然会触发报错。
  2. 模块使用规范不符:lmdb是Node.js模块,在Electron开启上下文隔离(contextIsolation: true)的情况下,渲染进程不能直接访问Node.js模块,需要通过预加载脚本安全暴露,或在主进程处理数据库操作后通过IPC供渲染进程调用。

修复方案

步骤1:安装lmdb

确保项目已安装依赖:

npm install lmdb

方案A:预加载脚本直接暴露lmdb方法

修改preload.js:

const { contextBridge } = require('electron');
const lmdb = require('lmdb'); // 先引入lmdb模块

// 用更清晰的名称暴露API
contextBridge.exposeInMainWorld('electronAPI', {
    openLMDB: (options) => lmdb.open(options)
});

修改renderer.js:

async function initDB() {
    try {
        const blocks = window.electronAPI.openLMDB({
            path: "./db/blocks",
            compression: true,
        });
        console.log('数据库打开成功', blocks);
        // 后续可执行blocks.put('key', 'value')等操作
    } catch (err) {
        console.error('打开数据库失败', err);
    }
}

initDB();

方案B:主进程处理数据库操作(推荐,更安全)

将数据库操作放在主进程,渲染进程通过IPC调用,符合Electron安全规范。

修改preload.js:

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
    openLMDB: (options) => ipcRenderer.invoke('open-lmdb', options),
    putDB: (key, value) => ipcRenderer.invoke('put-lmdb', key, value),
    getDB: (key) => ipcRenderer.invoke('get-lmdb', key)
});

修改main.js:

const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const lmdb = require('lmdb');

let blocksDB = null; // 保存数据库实例

function createWindow () {
    const win = new BrowserWindow({
        width: 1200,
        height: 800,
        autoHideMenuBar: true,
        icon: path.join(__dirname, 'gigatreelogosvv.ico'),
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            contextIsolation: true, // 保持安全模式
            nodeIntegration: false // 关闭nodeIntegration,默认已关闭
        }
    })

    win.loadFile('index.html')
    win.webContents.openDevTools()
}

// IPC监听:打开数据库
ipcMain.handle('open-lmdb', async (event, options) => {
    try {
        blocksDB = lmdb.open(options);
        return '数据库打开成功';
    } catch (err) {
        console.error(err);
        throw new Error('打开数据库失败:' + err.message);
    }
});

// IPC监听:写入数据
ipcMain.handle('put-lmdb', async (event, key, value) => {
    if (!blocksDB) throw new Error('数据库未打开');
    try {
        await blocksDB.put(key, value);
        return '写入成功';
    } catch (err) {
        throw new Error('写入失败:' + err.message);
    }
});

// IPC监听:读取数据
ipcMain.handle('get-lmdb', async (event, key) => {
    if (!blocksDB) throw new Error('数据库未打开');
    try {
        return blocksDB.get(key);
    } catch (err) {
        throw new Error('读取失败:' + err.message);
    }
});

// 应用生命周期处理
app.whenReady().then(() => {
    createWindow();
    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow();
    });
});

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit();
});

修改renderer.js:

async function initDB() {
    try {
        const result = await window.electronAPI.openLMDB({
            path: "./db/blocks",
            compression: true,
        });
        console.log(result);
        
        // 测试写入
        await window.electronAPI.putDB('testKey', 'testValue');
        console.log('写入完成');
        
        // 测试读取
        const value = await window.electronAPI.getDB('testKey');
        console.log('读取到数据:', value);
    } catch (err) {
        console.error(err.message);
    }
}

initDB();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 02:20:29