yijul 2023-02-15 14:07 采纳率: 100%
浏览 44
已结题

electron打包make后的exe模块运行不正常

产生的问题:我使用nodejs和electron开发应用,make后生成的exe可执行文件没有nodejs引入的模块涉及的功能。

左图是开发环境使用命令“npm start”正常运行的界面,右图是make后产生的exe文件运行界面。引入的模块是child_process(经测试,任何nodejs引入的模块都无法使用)。

img

开发环境:

开发使用的操作系统: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>

打包过程:

  1. 下载electron-forge并导入项目
    npm install --save-dev @electron-forge/cli
    npx electron-forge import
    
  1. 然后make
    npm run make
    
  • 写回答

6条回答 默认 最新

  • GISer Liu 2023-02-15 14:56
    关注

    根据你提供的信息,我推测这是因为 '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,等待打包完成。

    如果你需要使用其他插件打包,可以参考它们的文档进行配置。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 2月24日
  • 已采纳回答 2月16日
  • 修改了问题 2月15日
  • 创建了问题 2月15日

悬赏问题

  • ¥15 r语言神经网络自变量重要性分析
  • ¥15 基于双目测规则物体尺寸
  • ¥15 wegame打不开英雄联盟
  • ¥15 公司的电脑,win10系统自带远程协助,访问家里个人电脑,提示出现内部错误,各种常规的设置都已经尝试,感觉公司对此功能进行了限制(我们是集团公司)
  • ¥15 救!ENVI5.6深度学习初始化模型报错怎么办?
  • ¥30 eclipse开启服务后,网页无法打开
  • ¥30 雷达辐射源信号参考模型
  • ¥15 html+css+js如何实现这样子的效果?
  • ¥15 STM32单片机自主设计
  • ¥15 如何在node.js中或者java中给wav格式的音频编码成sil格式呢