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

如何在Electron Vue渲染进程中正确接入node-gyp原生模块?

Electron渲染进程无法加载原生Node模块的问题排查与修复

问题描述

使用electron-rebuild -v 24.4.0构建原生Node模块后,移入vite生成的electron@24.4.0空项目。主进程可正常导入并调用模块函数,但渲染进程操作时出现错误。本地Node.js版本为18.16.0(对应NODE_MODULE_VERSION 108),Electron版本为24.4.0(对应NODE_MODULE_VERSION 114),当前electron.vite.config.ts配置如下:

import { resolve } from 'path';
import { defineConfig, externalizeDepsPlugin } from 'electron-vite';
import vue from '@vitejs/plugin-vue';
import native from "rollup-plugin-native";

export default defineConfig({
  main: {
    plugins: [externalizeDepsPlugin()]
  },
  preload: {
    plugins: [externalizeDepsPlugin()]
  },
  renderer: {
    resolve: {
      alias: {
        '@renderer': resolve('src/renderer/src')
      }
    },
    plugins: [
      vue(),
      native(),
    ]
  }
});

原因分析

  1. 进程环境差异:主进程直接运行在Electron的Node.js环境中,原生模块加载逻辑与普通Node.js一致;而渲染进程默认是浏览器环境,即使开启Node集成,Vite的打包转译会修改模块路径或破坏原生模块结构,导致加载失败。
  2. 插件配置无效:rollup-plugin-native未正确适配Electron-Vite的渲染进程打包逻辑,无法保证原生模块的路径解析和版本兼容性。
  3. 版本关联问题:虽然用electron-rebuild构建了匹配Electron 24.4.0的模块,但渲染进程的打包配置未正确关联该模块,导致加载时可能调用了本地Node.js版本(NODE_MODULE_VERSION 108)的模块副本。

修复方案

方案1:调整渲染进程打包配置(直接开启Node集成)

  1. 开启渲染进程Node集成
    在主进程的窗口创建代码中,启用nodeIntegration并关闭contextIsolation:
import { BrowserWindow, app } from 'electron';
import path from 'path';

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  });

  mainWindow.loadURL('http://localhost:5173');
}

app.whenReady().then(createWindow);
  1. 修改electron-vite.config.ts
    移除rollup-plugin-native,将原生模块外部化,避免Vite转译:
import { resolve } from 'path';
import { defineConfig, externalizeDepsPlugin } from 'electron-vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  main: {
    plugins: [externalizeDepsPlugin()]
  },
  preload: {
    plugins: [externalizeDepsPlugin()]
  },
  renderer: {
    resolve: {
      alias: {
        '@renderer': resolve('src/renderer/src')
      }
    },
    plugins: [vue()],
    // 排除原生模块,不进行预构建
    optimizeDeps: {
      exclude: ['你的原生模块名称']
    },
    build: {
      rollupOptions: {
        // 标记原生模块为外部依赖,直接从node_modules加载
        external: ['你的原生模块名称']
      }
    }
  }
});
  1. 重新构建原生模块
    强制重新构建,确保模块完全匹配Electron版本:
electron-rebuild -f -v 24.4.0

方案2:使用预加载脚本桥接(安全推荐方案)

如果需要保持contextIsolation开启(Electron官方安全最佳实践),通过预加载脚本暴露原生模块API:

  1. 编写预加载脚本
    在src/preload/index.ts中添加:
import { contextBridge } from 'electron';
import yourNativeModule from '你的原生模块名称';

// 向渲染进程暴露安全的API
contextBridge.exposeInMainWorld('nativeAPI', {
  callNativeFunc: () => yourNativeModule.yourFunction()
});
  1. 配置主进程窗口
import { BrowserWindow, app } from 'electron';
import path from 'path';

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      contextIsolation: true,
      preload: path.join(__dirname, '../preload/index.js')
    }
  });

  mainWindow.loadURL('http://localhost:5173');
}

app.whenReady().then(createWindow);
  1. 渲染进程中调用API
// 在Vue组件或渲染进程代码中调用
window.nativeAPI.callNativeFunc();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:57:35