React调用Python脚本报错:child_process.spawn is not a function
问题描述
尝试在React应用中使用child_process模块执行Python脚本时,出现以下错误:
python.js:6 Uncaught TypeError: child_process.spawn is not a function
at runScript (python.js:6:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1)
at executeDispatch (react-dom.development.js:9041:1)
at processDispatchQueueItemsInOrder (react-dom.development.js:9073:1)
at processDispatchQueue (react-dom.development.js:9086:1)
at dispatchEventsForPlugins (react-dom.development.js:9097:1)
at react-dom.development.js:9288:1
代码示例
React代码
import React from 'react'; const child_process = require('child_process'); function MyComponent(props) { const runScript = () => { const pythonProcess = child_process.spawn('python', ['D:\site\web-app\src\python\teste.py', "teste", "arg2"]); pythonProcess.stdout.on('data', data => { console.log(data.toString()); }); pythonProcess.stderr.on('data', data => { console.error(data.toString()); }); pythonProcess.on('close', code => { console.log(`Script completed with code ${code}`); }); } return ( <button onClick={runScript}>Run Python Script</button> ); } export default MyComponent;
Python脚本
import sys print(sys.argv)
已尝试方案
直接导入spawn函数,问题依旧。
解决方案
错误原因
child_process是Node.js专属模块,仅能在Node.js运行环境中使用。浏览器环境(包括Web版React应用)没有该模块的支持,直接在前端代码中引用会导致找不到spawn方法,触发TypeError。
方案1:搭建后端接口(Web应用推荐)
通过Node.js后端服务调用child_process执行Python脚本,前端React通过HTTP请求调用后端接口获取结果:
后端代码(Express示例)
const express = require('express'); const child_process = require('child_process'); const app = express(); const port = 3001; app.use(express.json()); app.post('/run-python-script', (req, res) => { const { args } = req.body; // Windows路径需用双反斜杠转义 const pythonProcess = child_process.spawn('python', ['D:\\site\\web-app\\src\\python\\teste.py', ...args]); let output = ''; let error = ''; pythonProcess.stdout.on('data', (data) => { output += data.toString(); }); pythonProcess.stderr.on('data', (data) => { error += data.toString(); }); pythonProcess.on('close', (code) => { res.json({ code, output, error }); }); }); app.listen(port, () => { console.log(`Backend running on port ${port}`); });
修改后的前端React代码
import React from 'react'; function MyComponent(props) { const runScript = async () => { try { const response = await fetch('http://localhost:3001/run-python-script', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ args: ["teste", "arg2"] }), }); const result = await response.json(); console.log('脚本输出:', result.output); if (result.error) { console.error('脚本错误:', result.error); } console.log(`脚本执行完成,退出码: ${result.code}`); } catch (err) { console.error('请求后端失败:', err); } } return ( <button onClick={runScript}>Run Python Script</button> ); } export default MyComponent;
方案2:Electron桌面应用适配
如果你的React应用是基于Electron的桌面程序,可以通过Electron的IPC机制,让前端渲染进程通知主进程执行Python脚本:
主进程代码
const { app, BrowserWindow, ipcMain } = require('electron'); const child_process = require('child_process'); function createWindow() { const mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false } }); mainWindow.loadURL('http://localhost:3000'); // React开发服务器地址 } ipcMain.on('run-python-script', (event, args) => { const pythonProcess = child_process.spawn('python', ['D:\\site\\web-app\\src\\python\\teste.py', ...args]); pythonProcess.stdout.on('data', (data) => { event.reply('script-output', data.toString()); }); pythonProcess.stderr.on('data', (data) => { event.reply('script-error', data.toString()); }); pythonProcess.on('close', (code) => { event.reply('script-close', code); }); }); app.whenReady().then(() => { createWindow(); });
修改后的前端React代码
import React from 'react'; const { ipcRenderer } = window.require('electron'); function MyComponent(props) { const runScript = () => { ipcRenderer.send('run-python-script', ["teste", "arg2"]); ipcRenderer.on('script-output', (event, data) => { console.log(data); }); ipcRenderer.on('script-error', (event, data) => { console.error(data); }); ipcRenderer.on('script-close', (event, code) => { console.log(`脚本执行完成,退出码: ${code}`); }); } return ( <button onClick={runScript}>Run Python Script</button> ); } export default MyComponent;
内容的提问来源于stack exchange,提问作者cadelass

