如何在electron中运行express服务,并调用express服务?
目标
我是一名初学者,想要在electron项目中添加一个express服务。折腾了挺久的,看了很多教程资料,很多资料对初学者并不友好,这里将整个过程记录一下,希望对遇到同样问题的人有帮助
一、创建electron项目
初始化 npm 项目
Electron 应用基于 npm 搭建,以 package.json 文件作为入口点。 首先创建一个文件夹,然后在其中执行 npm init 初始化项目。
mkdir my-electron-app && cd my-electron-app
npm init
这条命令会帮您配置 package.json 中的一些字段。
npm install electron --save-dev
添加 .gitignore 文件
.gitignore 文件可以指定哪些文件和目录应该在Git中不被跟踪。 建议您复制一份 GitHub 的 Node.js gitignore 模板 到您项目的根目录,以避免将 node_modules 文件夹提交到版本控制系统中。
修改package.json文件
1.要执行这个脚本,需要在 package.json 的 scripts 字段中添加一个 start 命令,内容为 electron . 。 这个命令会告诉 Electron 在当前目录下寻找主脚本,并以开发模式运行它。
"start": "electron .",
2.入口点 应当是 main.js,对应修改。
"main": "main.js",
完整代码
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "Hello World!",
"main": "main.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Jane Doe",
"license": "MIT",
"devDependencies": {
"electron": "^28.1.0"
}
}
新建文件
1.在根目录下新建 main.js 文件,写入代码
// main.js
const { app, BrowserWindow } = require('electron/main')
const path = require('node:path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.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.在根目录下新建 preload.js 文件,写入代码
// preload.js
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron
// 除函数之外,我们也可以暴露变量
})
3.在根目录下新建 renderer.js 文件,写入代码
// renderer.js
const information = document.getElementById('info')
information.innerText = `本应用正在使用 Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), 和 Electron (v${versions.electron()})`
4.在根目录下新建 html文件,写入代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>Hello from Electron renderer!</title>
</head>
<body>
<h1>Hello from Electron renderer!</h1>
<p>👋</p>
</body>
</html>
检查electron项目是否能正常运行
终端运行
npm start
如果成功启动第一步就完成了
二、添加express服务
安装 Express 和其他所需依赖项:
npm install express body-parser cors
在修改main.js 中添加调用调用代码
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const server = express();
// 启用 CORS
server.use(cors());
// 解析 JSON 请求体
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
// 设置路由(根据需要添加)
server.get('/', (req, res) => {
res.send('Hello, Electron!');
});
// 启动服务器并监听端口(根据需要更改端口号)
server.listen(3000, () => {
console.log('Server started on port 3000,http://localhost:3000/');
});
修改后 完整代码main.js
const { app, BrowserWindow } = require('electron/main')
const path = require('node:path')
//添加子进程
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const server = express();
// 启用 CORS
server.use(cors());
// 解析 JSON 请求体
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
// 设置路由(根据需要添加)
server.get('/', (req, res) => {
res.send('Hello, Electron!');
});
// 启动服务器并监听端口(根据需要更改端口号)
server.listen(3000, () => {
console.log('Server started on port 3000,http://localhost:3000/');
});
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
// preload: path.join(__dirname, 'preload.js')
nodeIntegration: true, // 如果需要使用 Node.js 特性,请启用这个选项
contextIsolation: false // 为了安全起见,通常我们会启用这个选项,但在这里我们为了示例将其关闭了
}
})
// //创建子进程,直接打开当前目录下的server.js
// openExec = exec('node ./server.js', function (error, stdout, stderr) {
// if (error) {
// console.log(error.stack);
// console.log('Error code: ' + error.code);
// return;
// }
// console.log('使用exec方法输出: ' + stdout);
// console.log(`stderr: ${stderr}`);
// console.log(process.pid)
// });
//win.loadFile('index.html')
//修改入口
win.loadURL('http://localhost:3000')
// 打开开发者工具
win.webContents.openDevTools()
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
// 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
// 否则绝大部分应用及其菜单栏会保持激活。
if (process.platform !== 'darwin') {
app.exit();
// // 判断openExec是否存在,存在就杀掉node进程
// if (!openExec) {
// // console.log('openExec is null')
// } else {
// exec('taskkill /f /t /im node.exe', function (error, stdout, stderr) {
// if (error) {
// console.log(error.stack);
// console.log('Error code: ' + error.code);
// return;
// }
// console.log('使用exec方法输出: ' + stdout);
// console.log(`stderr: ${stderr}`);
// });
// }
}
})
运行测试
npm start
注意:
设置网络访问:
在 Electron 应用中,你可能需要设置一些网络访问策略,以便你的 Express 应用可以正常工作。你可以在 Electron 的主进程文件中设置这些策略。
在 macOS 上,你可能需要设置一个 .plist 文件来允许 Electron 应用访问网络。你可以在应用的 Contents/Resources/ 目录下创建一个这样的文件。例如:
<dict>
<key>com.apple.security.network.client</key>
<true/>
</dict>
打包测试
npm install --save-dev @electron/packager
#打包
electron-packager . --platform=win32 --arch=ia32,x64 --out=out --asar --overwrite --ignore=.git