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

Electron应用:如何从renderer.js引入Node模块?

嘿,我碰到过一模一样的问题!这是因为Electron从版本5开始,默认开启了上下文隔离(Context Isolation),同时关闭了Node集成,所以renderer进程没法直接requireNode模块——这是出于安全考虑的设计。下面给你几个可行的解决方案,按推荐程度排序:

方法1:使用Preload脚本(官方推荐,安全合规)

这是最符合Electron安全规范的做法,通过preload脚本在Node环境和renderer的浏览器环境之间建立安全的通信桥:

  1. 先创建一个preload.js文件(和你的main.js、renderer.js同级):
const { contextBridge } = require('electron');
const Store = require('electron-store');

// 初始化electron-store实例
const store = new Store();

// 把你需要的store方法暴露给renderer进程(只暴露必要的,减少安全风险)
contextBridge.exposeInMainWorld('electronStore', {
  get: (key) => store.get(key),
  set: (key, value) => store.set(key, value),
  delete: (key) => store.delete(key),
  clear: () => store.clear()
});
  1. 修改main.js里的窗口配置,指定preload脚本路径:
const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      // 指向刚才创建的preload.js
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true, // 保持开启,这是安全的关键
      nodeIntegration: false // 默认就是false,无需修改
    }
  });

  mainWindow.loadFile('index.html');
}

// 剩下的app生命周期代码保持不变
app.whenReady().then(() => {
  createWindow();
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});
  1. 最后在renderer.js里直接使用暴露的全局对象,不用再require了:
// 直接调用window上的electronStore对象
electronStore.set('username', 'tom');
console.log(electronStore.get('username')); // 输出'tom'

方法2:关闭上下文隔离与开启Node集成(不推荐,仅用于测试)

如果你只是做本地测试、完全不加载外部内容,可以用这种快速但不安全的方式:

修改main.js的webPreferences配置:

webPreferences: {
  contextIsolation: false,
  nodeIntegration: true
}

之后你就能在renderer.js里直接require了:

const Store = require('electron-store');
const store = new Store();

store.set('testKey', 'testValue');
console.log(store.get('testKey')); // 输出'testValue'

⚠️ 重要提醒:这种方式会让renderer进程拥有完整的Node.js权限,一旦你的应用加载了不可信的外部内容,恶意代码就能轻易获取系统权限,正式项目绝对不要用!

额外进阶:通过IPC在Main进程管理Store

如果需要更严格的安全控制,你可以把electron-store完全放在main进程里,通过IPC通信让renderer进程调用:

  1. 在main.js里初始化Store并监听IPC请求:
const { app, BrowserWindow, ipcMain } = require('electron');
const Store = require('electron-store');
const path = require('path');

const store = new Store();

// 监听renderer的get请求
ipcMain.handle('store-get', (_, key) => {
  return store.get(key);
});

// 监听renderer的set请求
ipcMain.handle('store-set', (_, key, value) => {
  store.set(key, value);
});

// 窗口创建代码和之前一致,记得指定preload
function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true
    }
  });
  mainWindow.loadFile('index.html');
}

// 生命周期代码省略...
  1. 修改preload.js暴露IPC调用方法:
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronStore', {
  get: (key) => ipcRenderer.invoke('store-get', key),
  set: (key, value) => ipcRenderer.invoke('store-set', key, value)
});
  1. 在renderer.js里用异步方式调用(因为IPC是异步的):
async function useStore() {
  await electronStore.set('age', 25);
  const userAge = await electronStore.get('age');
  console.log(userAge); // 输出25
}

useStore();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:09:25