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

Electron+React项目报错:无法解析child_process模块求助

Electron中调用child_process报错的解决方案

问题重现

执行npm start时出现以下错误:

Module not found: Error: Can't resolve 'child_process' in 'C:\Users\cantr\Desktop\Stage ingénieur KOMILFO SPORT\Sail Vision\React\react-electron\src\pages'

核心原因

child_process是Node.js核心模块,而你在Electron渲染进程的React组件中直接调用它——默认情况下,Electron渲染进程为了安全,关闭了Node API的访问权限,Webpack打包时会把它当作浏览器环境的依赖处理,自然找不到这个模块。

解决方法

方法1:临时启用渲染进程的Node集成(仅用于测试,不推荐生产)

在Electron主进程文件(如main.js)中创建BrowserWindow时,配置webPreferences开启Node集成:

const { BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true, // 开启Node API访问
      contextIsolation: false, // 必须关闭上下文隔离,否则Node集成不生效
    }
  });

  mainWindow.loadURL('http://localhost:3000'); // 加载React开发服务或打包后的HTML
}

app.whenReady().then(createWindow);

方法2:通过IPC通信让主进程调用child_process(官方推荐,安全)

这是符合Electron安全规范的做法,渲染进程通过IPC请求主进程执行Node操作,主进程负责调用Python脚本。

步骤1:修改Electron主进程(main.js)

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

let mainWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false, // 保持默认,关闭渲染进程Node权限
      contextIsolation: true, // 开启上下文隔离,保证安全
      preload: path.join(__dirname, 'preload.js') // 预加载脚本,用于暴露IPC接口
    }
  });

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

// 监听渲染进程的Python脚本调用请求
ipcMain.handle('run-python-script', async () => {
  return new Promise((resolve, reject) => {
    // 注意Python脚本的路径要和主进程运行目录对应,可使用绝对路径避免问题
    const pythonProcess = spawn('python', [path.join(__dirname, './hello.py')]);
    
    pythonProcess.stdout.on('data', (data) => {
      resolve(data.toString().trim()); // 将Buffer转为字符串并去除多余空格
    });
    
    pythonProcess.stderr.on('data', (err) => {
      reject(err.toString());
    });
  });
});

app.whenReady().then(createWindow);

步骤2:添加预加载脚本(preload.js)

用于在渲染进程和主进程之间建立安全的通信桥:

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

contextBridge.exposeInMainWorld('electronAPI', {
  runPythonScript: () => ipcRenderer.invoke('run-python-script')
});

步骤3:修改React组件(Home.js)

通过暴露的API调用Python脚本,同时修正React中class属性为className:

import React from "react";

class Home extends React.Component {
    constructor() {
        super();
        this.state = { fs_s5: 12 };
    }

    componentDidMount() {
        // 组件挂载后发起脚本调用
        window.electronAPI.runPythonScript()
          .then(data => {
            this.setState({ fs_s5: data });
          })
          .catch(err => {
            console.error('Python脚本执行失败:', err);
          });
    }

    render(){
        return(
        <div>
            <div className="home">
                <div className="template-1" id="temp1">
                <div className="panel-1">
                    <div className="panel-header">
                    <h1>Panel 1</h1>
                    <i className='bx bx-cog modal-trigger-panel'></i>
                    </div>
                    <div className="panel-body">
                    <div className="sec-5 modal-trigger-data" id="hs-sec-5">
                        <span className="h1" id="h1-fs-s5">{this.state.fs_s5}</span>
                        <h2>TWIST</h2>
                        <h3>s5</h3>
                    </div>
                    <div className="sec-4 modal-trigger-data" id="hs-sec-4">
                        <h1>--</h1>
                        <h2>TWIST</h2>
                        <h3>s4</h3>
                    </div>
                    <div className="sec-3 modal-trigger-data" id="hs-sec-3">
                        <h1>--</h1>
                        <h2>TWIST</h2>
                        <h3>s3</h3>
                    </div>
                    <div className="sec-2 modal-trigger-data" id="hs-sec-2">
                        <h1>--</h1>
                        <h2>TWIST</h2>
                        <h3>s2</h3>
                    </div>
                    <div className="sec-1 modal-trigger-data" id="hs-sec-1">
                        <h1>--</h1>
                        <h2>TWIST</h2>
                        <h3>s1</h3>
                    </div>
                    </div>
                </div>
                </div>
            </div>
        </div>    
        );
    }
}

export default Home;

额外提示:Python脚本优化

如果后续需要通过Flask接口获取数据,可在Python脚本中添加就绪标记,让主进程知道Flask服务已启动:

from __future__ import print_function
import time
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World! This is powered by Python backend."

if __name__ == "__main__":
   print(12)
   print("FLASK_SERVICE_READY") # 添加就绪标记
   time.sleep(5)
   app.run(host='127.0.0.1', port=5000, debug=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:50:32