产生的问题:我使用nodejs和electron开发应用,make后生成的exe可执行文件没有nodejs引入的模块涉及的功能。
左图是开发环境使用命令“npm start”正常运行的界面,右图是make后产生的exe文件运行界面。引入的模块是child_process(经测试,任何nodejs引入的模块都无法使用)。
开发环境:
开发使用的操作系统:windows 11企业版22H2
node版本:19.6.0
npm版本:9.4.1
electron版本:23.0.0
相关代码如上图所示,我在electron项目中的preload.js文件中添加了子进程模块child_process,在make后并没有起作用。preload.js具体代码如下:
const { fork } = require('child_process')
const netcheck = fork('./netcheck.js')
window.addEventListener('DOMContentLoaded', () => {
const status = document.getElementById('status')
netcheck.on('message', (m)=>{
netcheck.send('check')
status.innerText = m.data
})
netcheck.send('check')
})
子进程文件netcheck.js的代码如下:
const dns = require('node:dns')
process.on('message',()=>{
setTimeout(getNetstatus,3000)
})
function getNetstatus(){
dns.lookup('cloud.tencent.com',(err)=>{
if (err){
msg = {code:0,data:"网络出错,请检查网络连接"}
process.send(msg)
}else{
msg = {code:1,data:"网络连接正常"}
process.send(msg)
}
})
}
前端html、javascript、css都正常,仅仅是nodejs部分没有起作用。
上面看到的“正在检测网络状态”的字样是预先在html里设定好的。
以下是入口程序main.js的代码:
// main.js
const { app, BrowserWindow} = require('electron')
const { join } = require('path')
const createWindow = () => {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegrationInWorker: true,
preload: join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
mainWindow.webContents.openDevTools()
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
以下是index.html文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>检测</title>
<link type="text/css" rel="stylesheet" href="resources/bootstrap-icons.css">
<link type="text/css" rel="stylesheet" href="resources/main.css">
</head>
<body>
<div id="brand">
<i class="bi bi-globe2"></i><div><span>好抓</span>网络抓取客户端</div>
</div>
<div id="status">正在检测网络状态</div>
<div id="list" class="list-normal"></div>
<script type="text/javascript" src="resources/require.js" data-main="resources/index.js"></script>
</body>
</html>
打包过程:
npm install --save-dev @electron-forge/cli
npx electron-forge import
npm run make
根据你提供的信息,我推测这是因为 'child_process应用使用了不同的运行时(Chromium 浏览器)。如果没有正确打包 Node.js 核心模块,这些模块就不能在 Electron 应用中运行。
为了正确地打包 Node.js 核心模块,你可以使用electron-forge的一些插件,例如@electron-forge/plugin-webpack或@electron-forge/plugin-webpack-rc.这些插件可以在打包时将 Node.js 核心模块打包到 Electron 应用中。
以下是使用@electron-forge/plugin-webpack的步骤:
1.安装@electron-forge/plugin-webpack:
npm install --save-dev @electron-forge/plugin-webpack
2.在 '包文件中,添加以下配置:
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"name": "your-app-name"
}
}
],
"plugins": [
[
"@electron-forge/plugin-webpack",
{
"mainConfig": "./webpack.main.config.js",
"renderer": {
"config": "./webpack.renderer.config.js",
"entryPoints": [
{
"html": "./src/index.html",
"js": "./src/renderer.ts",
"name": "main_window"
}
]
}
}
]
]
}
}
3.在项目根目录下创建 'webpack.renderer.config.js
const path = require('path')
module.exports = {
target: 'electron-renderer',
entry: {
renderer: './src/renderer.ts'
},
resolve: {
extensions: ['.js', '.ts', '.jsx', '.tsx', '.json']
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
}
}
4.修改 'preload.js中加载child_process模块的方式,改为使用require加载,如下所示:
window.child_process = require('child_process');
5.重新运行npm run make,等待打包完成。
如果你需要使用其他插件打包,可以参考它们的文档进行配置。
你会不会没有权限啊?
没有权限保存,或者没有权限写入
你检查下看看
最后,您可以尝试在开发模式下使用 Electron 运行应用程序,并查看是否存在任何错误或警告信息。
提供一个参考讨论实例:https://segmentfault.com/q/1010000022996984?utm_source=tag-newest
看看在打包应用程序时是否包含了子进程模块,可以尝试在electron-forge的构建配置文件中添加asarUnpack选项,以便在构建过程中将模块解压到应用程序包中。