likes
comments
collection
share

React+Electron开发桌面应用以及踩的坑

作者站长头像
站长
· 阅读数 27

💡 根据 遗忘曲线:如果没有记录和回顾,6天后便会忘记75%的内容,所以特此记录下Electron 踩的坑

Electron 官网

www.electronjs.org/zh/docs/lat…

前言

最近公司 Electron 项目需求,经过对比,还是用比较喜欢的React+ Electron的形式开发,网上也有挺多从 0 开始建项目,但亲手实践了之后还是遇到了不少问题,在此记录下,希望能帮到遇到类似问题的银。

React+Electron开发桌面应用以及踩的坑

线上看的比较好比较详细的一些帖子

blog.csdn.net/weixin_4401…

步骤

安装 运行

1. 用 create-react-app创建一个 react项目

create-react-app "项目名"

我是将 create-react-app安装到了全局

2. 添加 Electron包到本地环境

!!!此处我装在了 desktop 文件夹下,详解看第三部

npm i Electron -D

顺带也把 electron-builder这个包装上,后面打包要用

同时我也装了识别当前是开发环境还是本地环境的 cross-env

版本如下

React+Electron开发桌面应用以及踩的坑

Node.JS 版本是 v16.20.2

3. 我的目录结构 (此处参考了第一篇文章,觉得这种分离很干净)

React+Electron开发桌面应用以及踩的坑

Electron相关的都放在了 desktop 文件夹下,并且 Electronelectron-buildercross-env都装在了这个目录下,后续本地启动和打包都在这个层级下输入命令启动

当然也可以直接放在外层, 外层的package.json显示,只需要在Electron入口文件中路径能指过去就 OK

4. main 入口文件 js

React+Electron开发桌面应用以及踩的坑

// main.js
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')

// const path = require('path')
const path = require('node:path')

const isDevelopment = process.env.NODE_ENV === 'development'

const createWindow = () => {
    // Create the browser window.
    const mainWindow = new BrowserWindow({
        // width: 800,
        // height: 600,
        width: 1160,
        height: 752,
        minHeight: 632,
        minWidth: 960, 
        show: true, //布尔值,指定创建窗口后是否立即显示
        frame: true, //布尔值,指定是否显示窗口的外部框架(包括标题栏和控制按钮)(无边框)
        title: 'WuKong',
        icon: path.resolve(__dirname, './assets/windows.png'),

        webPreferences: {
            preload: path.join(__dirname, 'preload.js')
        }
    })


    if (isDevelopment) {
        //本地环境
        mainWindow.loadURL('http://localhost:3000/')
    } else {
        const entryPath = path.resolve(__dirname, '../build/index.html')  //这个位置是关键,一定要指到react项目打包后的位置
        console.log('entryPath====', entryPath);
        mainWindow.loadFile(entryPath)
    }

    // 用来解决载入闪白屏问题
    mainWindow.once('ready-to-show', () => {
        mainWindow.show()
    })

    // 打开开发工具
    mainWindow.webContents.openDevTools()
}


// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
    createWindow()
    
    app.on('activate', () => {
        // 在 macOS 系统内, 如果没有已开启的应用窗口
        // 点击托盘图标时通常会重新创建一个新窗口
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})

// 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 因此, 通常
// 对应用程序和它们的菜单栏来说应该时刻保持激活状态, 
// 直到用户使用 Cmd + Q 明确退出
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
})

// 在当前文件中你可以引入所有的主进程代码
// 也可以拆分成几个文件,然后用 require 导入。

这里的 path.resolvepath.join都是 Node.js 中的方法,目的是拼接路径,前面的 __dirname变量是当前位置

5. desktop 目录下的 package.json文件

{
  "name": "desktop",
  "productName": "WuKong",
  "version": "1.0.0",
  "description": "",
  "main": "main/index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "dev-electron": "cross-env NODE_ENV=development electron main/index.js",
    "prod-electron": "cross-env NODE_ENV=production electron main/index.js",
    "build-electron-win64": "electron-builder -w --x64"
  },
  "build": {
    "productName": "WuKong",
    "appId": "wuKong.electron.app",
    "files": [
      "build/**/*",
      "main/**/*"
    ],
    "directories": {
      "output": "dist"
    },
    "nsis": {
      "oneClick": false,
      "allowElevation": true,
      "allowToChangeInstallationDirectory": true,
      "installerIcon": "./main/assets/logo.ico",
      "uninstallerIcon": "./main/assets/logo.ico",
      "installerHeaderIcon": "./main/assets/logo.png",
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true,
      "shortcutName": "WuKong"
    },
    "win": {
      "icon": "./main/assets/logo.ico",
      "artifactName": "${productName}-${version}-${os}-${arch}.${ext}",
      "target": "nsis"
    },
    "extends": null
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "cross-env": "^7.0.3",
    "electron": "^31.0.2",
    "electron-builder": "^24.13.3"
  }
}

这个文件夹下一开始没有package.json,可以 npm init一下

具体字段大概都什么意思第一篇文章写的很全,可以去照着看

dev-electron 在本地环境运行

prod-electron 再生产环境运行

build-electron-win64 打包

命令不重要,这个自己随便定义,着重看 script 后面执行的内容

React+Electron开发桌面应用以及踩的坑

其中的 "main": "main/index.js",要指向上面的 main 文件夹下的 index.js

6. 运行

执行我的本地环境

npm run dev-electron

看 main 下 js 文件中配置的内容

if (isDevelopment) {
  //本地环境
  mainWindow.loadURL('http://localhost:3000/')
} else {
  const entryPath = path.resolve(__dirname, '../build/index.html')
  console.log('entryPath====', entryPath);
  mainWindow.loadFile(entryPath)
}

输入上面的命令执行的 mainWindow.loadURL('http://localhost:3000/'),所以此时你得保证,你得本地 3000 端口有服务在运行着,react 本身项目启动时默认端口就是这个,所以要在之前 npm start启动本身项目

到这里如果配置什么都 OK 的话 应该很轻松就能看到本来 React 项目的内容

React+Electron开发桌面应用以及踩的坑

我这里简单把原来的 react logo 换了个图标 卍,解!!!

React+Electron开发桌面应用以及踩的坑

然后测试执行身产环境的命令 npm run prod-electron

执行的是上面 else 内的内容

const entryPath = path.resolve(__dirname, '../build/index.html')
console.log('entryPath====', entryPath);
mainWindow.loadFile(entryPath)

我这里遇到了第一个坑,页面空白,同时后面打包也会白屏这俩是一个问题,就是文件路径指向问题,这块放到后面白屏问题说

ok 假如成功运行看到的是和上面 页面相同的效果,这里右侧开了控制台是配置里面设置的

React+Electron开发桌面应用以及踩的坑

大家记得上到正式环境时给关掉

打包

这里用到了 electron-builder这个工具,上面还没装得,装一下

报错 1 - 网络

我这里打包过程中遇到好几个错,首先是提示下载 download ... 这个包 winCodeSign-2.6.0.7z,这个问题看网上应该是 GitHub 在国内网络不稳,老是下载失败造成的,网上的解决方法是直接把这个包下载下来放到本地 electron文件内,试了可行。

如果不行我还打算开个梯子试下,没用上,如果各位包放到本地还是报错的话可以试试看

下面说下包下载完后具体放到哪个位置,因为设备问题,我只试了 window 环境下的

通常在这个位置

C:\Users\Mr.Liu\AppData\Local

React+Electron开发桌面应用以及踩的坑

这两个文件夹下的 Cache中,一开始我只放在了 builder 中,不好时,两个都放了之后不报那个错了

React+Electron开发桌面应用以及踩的坑

React+Electron开发桌面应用以及踩的坑

报错 2 - 图片

如果打包时控制台提示和 图片相关的,比如某某 logo.icon图片有问题,我这边是因为图意省事,直接在网上下的 .png格式图片,直接改了后缀名,导致打包时提示非法无法识别,乖乖上网上找了专门的 ico 网站生成的.ico格式图片就好了

React+Electron开发桌面应用以及踩的坑

我用的这个网站 如果大家看的时候还能打开可以直接拿去用

www.toolhelper.cn/Image/Image…

打包成功后会在 dist目录下生成这种文件

React+Electron开发桌面应用以及踩的坑

其中外层的 x64.exe是安装包,内部的.exe是直接可以启动的

报错 3 - 页面空白

这里回到本地启动生成环境那一步,假如这里启动后是白屏并且,控制台报这种错 Failed to load resource: net::ERR_FILE_NOT_FOUND

那么生成环境还有打包后的 window 软件都会这样,本质是没找到指向的index.html文件

打开打包好的index.html(此时应该是一行代码),恢复一下代码格式可以看到

React+Electron开发桌面应用以及踩的坑

这里是原 react 项目设置下打包遵循相对路径就可以了,在外层的 package.json里面写这个

"homepage": "./",

React+Electron开发桌面应用以及踩的坑

然后在打包 (打包外层的 react 项目)npm start再同样的方法看下 index.html

React+Electron开发桌面应用以及踩的坑

发现已经变过来了,网上有同志手动改这个文件的,貌似也行,但不太优雅

React+Electron开发桌面应用以及踩的坑

然后将打包好的文件放到内部的 build 文件夹中,因为我的 main 下的 js 路径指向的是内部的 build 文件夹,如果大家直接在外部写的,指向对路径就可以

React+Electron开发桌面应用以及踩的坑

然后执行打包命令

build-electron-win64

直接看打完包的dist文件

React+Electron开发桌面应用以及踩的坑

完事,下班, 卍解!

React+Electron开发桌面应用以及踩的坑

转载自:https://juejin.cn/post/7384781386832298022
评论
请登录