快速填坑Electron&Vue3项目框架

1,217 阅读3分钟

在以前的文章中,我曾经使用过electron + vue2打造过番茄钟项目,但是当时对配置的描述感觉不够详细,现在随着使用,有些配置命令也可以更新了。

以前的文章:

现在使用最新的Vue3 + Vite来创建Electron项目吧!!!

PS:本文主要是为整理项目结构和快速建立框架而写,不会过多涉及业务。文章是我总结出的Electron快速开发途中可能遇到的问题和比较便利的方法,例如对于打包使用mjs和独立json进行配置。

项目创建和结构

一、 创建项目

使用vite命令创建项目,框架选择vue3,因为个人开发,不对typescript进行配置。

创建项目:yarn create vite time-hourglass --template vue

在项目生成后,可根据自己习惯在项目中创建相应文件夹

二、项目结构

以下是我项目文件夹架构:

p1.png

  1. electron electron文件夹中主要存放项目涉及到后端的逻辑代码,包括连接sqlite数据库和创建项目窗体等内容,使用node
  2. src src文件夹主要存放项目涉及到前端页面的代码
    • assets: 资源文件夹,存放静态图片、字体包、iconfont、公共css文件等
    • components: 存放vue组件
    • hooks: 存放可抽离出来的公共方法,包括ipcRenderer与后台交互的逻辑方法
    • model: 存放class类
    • router:存放路由配置内容
    • store:使用pinia管理涉及到全局的状态变量
  3. script script文件夹存放mjs文件,用于配置electron项目运行和打包

npm包

以下是我项目中使用的npm包:

"dependencies": {
	"element-plus": "^2.7.6",
	"less": "^4.2.0",
	"less-loader": "^12.2.0",
	"pinia": "^2.1.7",
	"sqlite3": "5.1.4",
	"vue": "^3.4.29",
	"vue-router": "^4.4.0"
},
"devDependencies": {
	"@types/node": "^20.14.9",
	"@vitejs/plugin-vue": "^5.0.5",
	"electron": "23.1.1",
	"electron-builder": "23.6.0",
	"unplugin-auto-import": "^0.17.6",
	"unplugin-vue-components": "^0.27.2",
	"vite": "^5.3.1"
}

对于配置项目使用的sqlite3electron包的版本还是有要求的,其他npm包使用最新即可。

sqlite3版本最好使用5.1.7之前的版本,否则在打包时会出现问题。electron也是如此,如果项目不用sqlite3,那么正常打包electron用最新版本也是可以。

PS:出现的问题会在文末统一进行说明,比如遇到electron安装失败、sqlite3安装失败


mjs配置

在配置package.json脚本时,发现将electron的打包和运行设置都写在里面过于臃肿,所以上网查找了下,发现可以分离出来,写在mjs当中。

package.json脚本只需要写入运行对应的mjs即可

"electron:dev": "nodemon ./script/dev.mjs",
"electron:build": "node ./script/build.mjs"

创建一个exec.mjs文件,里面主要是nodeexecspawn封装方法

import { exec, spawn } from "child_process";

/**
 * 执行shell命令
 * 
 * @param 命令
 * @returns 
 */
export function useExec(shell) {
  ...
}

export function useSpawn(shell, arr = []) {
  return new Promise((res, rej)=>{
    let result = spawn(shell, arr, {
      stdio: 'inherit',
      shell: process.platform === 'win32'
     });
    result.on('data', (data) => {
      res(data.toString());
    })
    // 进程结束
    result.on('close', (code)=>{
      res(`${shell} process has exit`);
    })
    result.on('error', (err) => {
      rej(err.error)
    })
  })
}

比如创建一个dev.mjs文件,用于运行项目,内部使用spawn来同时启动vue页面和electron 代码如下:

// 使用mjs,以便使用import方式引用模块
// 也可以把改为dev.js去使用require.
// es规范下__dirname需要自己手动定义.
import { createServer } from "vite";
import { useExec, useSpawn } from "./exec.mjs";
import electron from "electron"; // 引入
import path from "path";
const __dirname = path.resolve();
const server = await createServer({
  configFile: path.resolve(__dirname, "./vite.config.js"), // 引用根目录配置文件
});

const { config } = await server.listen();
// console.log(config.server.port); // 获取到了vite开启的端口
server.printUrls(); // 打印服务器地址

let electronProcess = useSpawn('yarn electron:serve'); // 开启子进程
electronProcess.then(res=>{
  console.log(res);
})

也可以设置一个electron-build.json,配置打包的文件内容。

  • 为了减少打包后的体积,可以在files中将自己不需要打入的文件移出,比如:node_modules
  • 当前打包的文件查看内容方便一些,可以先不设置asar打包,这样能看到打包文件夹目录的层级和结构关系
  • 打包生成的electron项目文件夹名和位置,可以通过在directories中设置

其他配置可参考官网:electron-builder

{
    "productName": "time-hourglass",
    "appId": "com.timehourglass.app",
    "directories": {
        "output": "./newdist"
    },
    "asar": false,
    "files": [
        "!node_modules"
    ]
}

electron配置

electron文件夹中主要写后台逻辑

如创建窗体、连接数据库等操作,里面大部分代码都不必细说,根据官网文档来即可。

  1. 创建窗体时可以根据自己需求设置frameresizableicon等内容,并且将preload.js配置在webPreferences中。
  2. preload.js中通过contextBridge在隔离的上下文之间创建安全、双向、同步的桥梁,API文档:contextBridge | Electron 中文网 (nodejs.cn)
  3. 环境判断可以通过app.isPackaged属性,然后webContents.openDevTools控制开发者工具是否打开。
  4. Tray来创建系统托盘,可以设置托盘图标、右键目录、双击效果等内容。
  5. 配置ipc连接命令可以使用ipcMain.onipcMain.handle
    • ipcMain 模块是 事件触发器。当在主进程中使用时,它处理从渲染器进程(网页)发送的异步和同步消息。从渲染器发送的消息将被发送到该模块。
    • on 主要用于处理渲染进程发送的异步消息
    • handle 主要用于处理渲染进程发送的同步消息请求,并返回响应。

遇到的问题

一、sqlite3安装失败

直接yarn add sqlite3出错,安装失败,使用"sqlite3": "^5.1.4"添加在package.json中安装成功。

也可能由于node版本原因,可以使用18.x

二、electron安装失败

出现HTTPError: Response code 404 (Not Found)问题,修改yarn config中配置。

  • 使用yarn config list可查看配置
  • 使用yarn config set electron_mirror https://npmmirror.com/mirrors/electron/重新设置地址
  • 使用yarn config delete ***可删除某段配置

三、Request Autofill.enable failed

不会有什么影响,因为使用mainWindow.webContents.openDevTools();打开控制台时会出现

四、Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/vue-router.js?v=e3974419' does not provide an export named 'RouteRecordRaw'

vue-router^4.4.0中,没有RouteRecordRaw了,引入后会报错

五、electron打包失败 errorOut=prebuild-install warn This package does not support N-API version 31.1.0

查找资料发现是sqlite3版本需要在5.1.7之前,在此之后打包都会出错

然后安装指定sqlite3@5.1.6失败,需要使用 python –V查看版本,需要python3环境

python3环境下能够成功安装sqlite3@5.1.6

后来的打包还是失败,因为sqlite3的缘故,一气之下直接换成以前的electron版本,成功了

当前版本:

npm包版本
electron23.1.1
electron-builder23.6.0
sqlite35.1.4

六、打包后页面空白

设置的mainWindow.loadURL(file://${path.resolve(__dirname, '../../')}/dist/index.html);路径原因,使用path.resolve(__dirname, '../../')需要根据当前main.js文件和vue打包的dist文件夹路径来设置

七、打包后体积过大,node_modules也在里面

build.json设置中,写files配置,写入"!node_modules",打包后文件中就不会出现node_modules文件夹了