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

Electron应用中require语句执行失败问题求助

问题解决:Electron渲染进程中无法执行Node.js模块调用

你的问题核心是Electron渲染进程的安全限制,加上脚本模块类型不匹配,导致代码卡在require调用处无法继续执行。下面是具体的修复步骤:

1. 调整Electron主进程配置,开放Node.js API访问权限

Electron默认禁用渲染进程的Node.js集成并开启上下文隔离,这是安全默认设置。你需要在主进程的窗口配置里修改:

// main.js(你的Electron主进程文件)
const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      // 允许渲染进程使用Node.js API
      nodeIntegration: true,
      // 关闭上下文隔离(简化场景下的设置,若需更高安全性可看后续可选方案)
      contextIsolation: false
    }
  });

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

app.whenReady().then(() => {
  createWindow();
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

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

2. 修正HTML中的脚本类型

你给script标签设置了type="module",但脚本使用的是CommonJS规范的require,二者不兼容会触发语法错误。直接移除该属性:

<!-- 修改后的index.html -->
<html>
     <head>
         <title>Display Screenshot</title>
     </head>
     <body>
         <img id="screenshotImage" src="" alt="Screenshot">
         <h1 id="test_id">No</h1>
         <!-- 移除type="module" -->
         <script src="get_screenshot.js"></script>
     </body>
</html>

3. 修复脚本中的异步逻辑与二进制数据处理

util.promisify(childProcess.exec)返回的是Promise对象,必须用async/await处理才能正确获取结果;同时adb输出的是二进制PNG数据,需要转换为base64格式才能在页面显示:

// 修改后的get_screenshot.js
const util = require('util');
const childProcess = require('child_process');

// 现在这行代码可以正常执行
document.getElementById('test_id').innerHTML = "Require passed!";

const exec = util.promisify(childProcess.exec);

// 将screenshot改为async函数以支持await
const screenshot = async () => {
    try {
        // 用await等待exec执行完成
        const { stdout, stderr } = await exec('adb exec-out screencap -p');
        if (stderr) {
            console.error('执行命令出错:', stderr);
            return;
        }
        // 把二进制stdout转换为base64字符串
        const screenshotData = Buffer.from(stdout).toString('base64');
        displayScreenshot(screenshotData);
    } catch (err) {
        console.error('捕获到错误:', err);
    }
}

function displayScreenshot(screenshotData) {
    const imageData = `data:image/png;base64,${screenshotData}`;
    const imgElement = document.getElementById('screenshotImage');
    imgElement.src = imageData;
}

screenshot();

可选:更安全的预加载脚本方案(推荐)

如果需要兼顾安全性,可以保留上下文隔离,通过预加载脚本暴露所需API:

  1. 主进程配置调整:
webPreferences: {
  contextIsolation: true, // 保持开启
  preload: path.join(__dirname, 'preload.js') // 指定预加载脚本路径
}
  1. 编写preload.js:
const { contextBridge } = require('electron');
const util = require('util');
const childProcess = require('child_process');
const exec = util.promisify(childProcess.exec);

// 向渲染进程暴露安全的API
contextBridge.exposeInMainWorld('electronAPI', {
  takeScreenshot: async () => {
    const { stdout, stderr } = await exec('adb exec-out screencap -p');
    if (stderr) throw new Error(stderr);
    return Buffer.from(stdout).toString('base64');
  }
});
  1. 修改get_screenshot.js调用暴露的API:
document.getElementById('test_id').innerHTML = "Require passed!";

const screenshot = async () => {
    try {
        const screenshotData = await window.electronAPI.takeScreenshot();
        displayScreenshot(screenshotData);
    } catch (err) {
        console.error(err);
    }
}

function displayScreenshot(screenshotData) {
    const imageData = `data:image/png;base64,${screenshotData}`;
    const imgElement = document.getElementById('screenshotImage');
    imgElement.src = imageData;
}

screenshot();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:37:42