Vue+Electron打包桌面应用(从零到一完整教程)

文章目录

一.使用vite+vue3+js方式

切记,整个项目的json文件不能有注释,及时没报错也不行,否则运行命令时还是有问题

一.构建桌面应用

1.创建项目

js 复制代码
 npm create vite@latest
 或者
 npm init vite@latest
 // 选择vue3+js或者vue3+ts

2. 安装依赖运行项目

js 复制代码
// 进入项目安装依赖
npm install
// 运行项目
npm run dev

3.配置Electron

js 复制代码
npm install electron  //这里建议用镜像,不然太慢

4.修改配置文件

1) vite.config.js
js 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  base: './',	// 新增,打包的dist文件的index.html引入资源css/js的路径,这里使用相对路径,预防找不到的问题
  plugins: [vue()]
})
2)main.js(项目根目录新增)

此为electron运行的入口文件

js 复制代码
// main.js

// 控制应用生命周期和创建原生浏览器窗口的模组
const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
  // 创建浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  // 加载 index.html
  mainWindow.loadFile('dist/index.html') // 此处跟electron官网路径不同,需要注意

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

// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    // 通常在 macOS 上,当点击 dock 中的应用程序图标时,如果没有其他
    // 打开的窗口,那么程序会重新创建一个窗口。
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

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

// 在这个文件中,你可以包含应用程序剩余的所有部分的代码,
// 也可以拆分成几个文件,然后用 require 导入。
3)preload.js(项目根目录下新增)
js 复制代码
// preload.js

// 所有Node.js API都可以在预加载过程中使用。
// 它拥有与Chrome扩展一样的沙盒。
window.addEventListener('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector)
    if (element) element.innerText = text
  }

  for (const dependency of ['chrome', 'node', 'electron']) {
    replaceText(`${dependency}-version`, process.versions[dependency])
  }
})
4)package.json
js 复制代码
{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "main.js",  // 新增
  //"type": "module", 创建项目自带的这个要删除,否则会有问题
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron:serve": "electron ."  //新增 electron运行命令
  },
  "dependencies": {
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "vite": "^4.4.5"
  }
}

5.打包vue项目

js 复制代码
npm run build

6.运行electron

js 复制代码
yarn electron:serve
或者
npm run electron:serve

到这一步基本完成了,后面再新增一下热更新及打包的配置,可以接着往下看

二.热更新开发环境

1. 编辑main.js

将mainWindow.loadFile('dist/index.html')更新为mainWindow.loadURL("http://localhost:5173"),更新后的文件如下所示:

js 复制代码
// main.js

// 控制应用生命周期和创建原生浏览器窗口的模组
const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
  // 创建浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  // 加载 index.html
  // mainWindow.loadFile('dist/index.html') 将该行改为下面这一行,加载url
  mainWindow.loadURL("http://localhost:5173") //这里改成自己的项目启动端口

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

// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    // 通常在 macOS 上,当点击 dock 中的应用程序图标时,如果没有其他
    // 打开的窗口,那么程序会重新创建一个窗口。
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

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

// 在这个文件中,你可以包含应用程序剩余的所有部分的代码,
// 也可以拆分成几个文件,然后用 require 导入。

2. 同时开启vite和electron服务

为了使vite和electron正常运行,需要先运行vite,使得其开发服务器的url可以正常访问,然后再开启electron去加载url。

此处需要安装两个库:

  • concurrently:阻塞运行多个命令,-k参数用来清除其它已经存在或者挂掉的进程
  • wait-on:等待资源,此处用来等待url可访问

安装命令为

js 复制代码
yarn add -D concurrently wait-on
或者
npm install -D concurrently wait-on

接着更新文件package.json,scripts新增两条命令:

js 复制代码
{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "main.js",  
  //"type": "module", 创建项目自带的这个要删除,否则会有问题
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron": "wait-on tcp:5173 && electron .",  //新增更新1(这里改成自己的项目启动端口)
    "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\"" //新增更新2  
  },
  "dependencies": {
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "vite": "^4.4.5"
  }
}

3.运行

现已添加两条命令:

  • yarn electron为等待tcp协议5173端口可访问,然后执行electron
  • yarn electron:serve为阻塞执行开发服务器运行和yarn electron命令

运行项目只要执行命令yarn electron:serve或者npm run electron:serve即可,当修改项目文件时,桌面应用也将自动更新。

到现在为止,热更新也已经完毕,最后一部分就是打包操作

三.打包操作

先说结论,重点还是在于mainWindow.loadURL()。

打包后还是加载http://localhost:5173是无法运行的,因此,此处需要先用vite打包好,然后使用electron-builder加载vite打包后的文件进行打包。

为了代码能够根据不同环境在运行时加载http://localhost:5173,在打包时加载文件,此处需要使用环境变量来切换生产和开发环境。

实现

1. 环境变量

此处使用环境变量NODE_ENV来切换生产和开发环境,生产环境为NODE_ENV=production,开发环境为NODE_ENV=development,若有其它如release等环境可在此基础上拓展。

2. 创建electron文件夹

在项目根目录下创建文件夹electron,将main.js和preload.js文件移动进来.

3. 编辑electron/main.js

该文件主要是需要根据环境变量切换electron加载的内容,修改内容如下:

js 复制代码
// main.js

// 控制应用生命周期和创建原生浏览器窗口的模组
const { app, BrowserWindow } = require('electron')
const path = require('path')

const NODE_ENV = process.env.NODE_ENV  //新增
// const NODE_ENV = 'development'  // 判断开发或生产模式(建议写成这种,开发模式就可以用,等即将打包了再把这个变量换成打包模式)

function createWindow () {
  // 创建浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  // 加载 index.html
  // mainWindow.loadFile('dist/index.html') // 此处跟electron官网路径不同,需要注意
  mainWindow.loadURL(
    NODE_ENV === 'development'
    ? 'http://localhost:5173'
    :`file://${path.join(__dirname, '../dist/index.html')}`
  ); // 新增
  // 打开开发工具
  if (NODE_ENV === "development") {
    mainWindow.webContents.openDevTools()
  } // 新增
}

// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    // 通常在 macOS 上,当点击 dock 中的应用程序图标时,如果没有其他
    // 打开的窗口,那么程序会重新创建一个窗口。
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

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

// 在这个文件中,你可以包含应用程序剩余的所有部分的代码,
// 也可以拆分成几个文件,然后用 require 导入。

4. 编辑package.json

首先修改main 属性,将main: main.js改为main: electron/main.js。

接着,编辑build属性:

js 复制代码
{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "electron/main.js",  // 修改入口文件位置
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron": "wait-on tcp:5173 && electron .",
    "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\""
  },
  "build": {
    "appId": "com.dweb.demo",  //包id com.dweb.项目名
    "productName": "ElectronApp", // 项目名
    "copyright": "Copyright © 2021 <your-name>", // 版权信息
    "mac": {
      "category": "public.app-category.utilities"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "directories": {
      "buildResources": "assets", //静态文件资源获取目录
      "output": "dist_electron" // 打包位置,会新建到项目根目录
    }
  },
  "dependencies": {
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "concurrently": "^8.2.1",
    "vite": "^4.4.5",
    "wait-on": "^7.0.1"
  }
}

然后,更新scripts属性。

此处需要先安装两个库:

  • cross-env: 该库让开发者只需要注重环境变量的设置,而无需担心平台设置
  • electron-builder: electron打包库
js 复制代码
yarn add -D cross-env electron-builder
或者
npm install -D cross-env electron-builder

更新后的scripts如下:

js 复制代码
{
  "dev": "vite",
  "build": "vite build",
  "serve": "vite preview",
  "electron": "wait-on tcp:5173 && cross-env NODE_ENV=development electron .", // 此处需要设置环境变量以保证开发时加载url
  "electron:serve": "concurrently -k \"yarn dev\" \"yarn electron\"",
  "electron:build": "vite build && electron-builder" // 新增打包命令
}

最后,更新后的package.json完整内容如下:

js 复制代码
{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "electron/main.js",  // 修改入口文件位置
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron": "wait-on tcp:5173 && electron .",
    "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\"",
    "electron:build": "vite build && electron-builder" // 新增打包命令
  },
  "build": {
    "appId": "com.dweb.demo",  //包id com.dweb.项目名
    "productName": "ElectronApp", // 项目名
    "copyright": "Copyright © 2021 <your-name>", // 版权信息
    "mac": {
      "category": "public.app-category.utilities"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "directories": {
      "buildResources": "assets", //静态文件资源获取目录
      "output": "dist_electron" // 打包位置,会新建到项目根目录
    }
  },
  "dependencies": {
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "concurrently": "^8.2.1",
    "vite": "^4.4.5",
    "wait-on": "^7.0.1"
  }
}

5.打包

js 复制代码
yarn electron:build
或者
npm run electron:build

报错了:Package "electron" is only allowed in "devDependencies". Please remove it from the "dependencies" section in your package.json.

这段意思就是说electron不允许在开发依赖,需要换到运行依赖里面,改完后package.json如下:

js 复制代码
{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "electron/main.js",  // 修改入口文件位置
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron": "wait-on tcp:5173 && electron .",
    "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\"",
    "electron:build": "vite build && electron-builder" // 新增打包命令
  },
  "build": {
    "appId": "com.dweb.demo",  //包id com.dweb.项目名
    "productName": "ElectronApp", // 项目名
    "copyright": "Copyright © 2021 <your-name>", // 版权信息
    "mac": {
      "category": "public.app-category.utilities"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "directories": {
      "buildResources": "assets", //静态文件资源获取目录
      "output": "dist_electron" // 打包位置,会新建到项目根目录
    }
  },
  "dependencies": {
    // 将开发依赖换到了运行依赖里面
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "concurrently": "^8.2.1",
    "vite": "^4.4.5",
    "wait-on": "^7.0.1",
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  }
}

打包完成之后,会多出两个文件夹distdist_electron

如果打包失败,或者一直卡着一个地方,是因为打包会产生依赖包,都是从github下载的,需要vpn,或者国内镜像可以解决,具体使用淘宝镜像方法可以看本博客最后,亲测有效

至此,所有基本结束,上面这一堆参考了这个博主的文章,各位也可以看看

二.使用vite+vue3+Ts方式(某大佬已经搭建好了,只能Ts)

使用某大佬配置好的框架,只支持ts版本,没有选择项(vite+vue3+ts)

方法很简单

  1. 执行命令创建项目
    npm create electron-vite
    首次进入会下载项目依赖,会询问是否下载,输入y即可
    然后输入项目名回车即可创建完毕
  2. 安装依赖
    npm install
  3. 运行项目
    npm run dev
    执行命令以后会在electron窗口运行
  4. 打包exe
    npm run dev
    (大佬已经集成了热部署,代码更新窗口也更新)

三.使用vue-cli脚手架方式(支持vue2/3)

1.Node版本要求

本人用的是v16.20.2,

原本我用的是18版本结果打包一直有问题:报错:Error: error:0308010C:digital envelope routines::unsupported

后来查了大量资料找到了原因:因为 node.js V17版本中最近发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制

当然针对17版本以上也有办法解决,本人使用了最笨的方法就是降低版本到v16.20.2,大家可以看以下这篇博客尝试其他解决办法
快速解决Error: error:0308010C:digital envelope routines::unsupported的三种解决方案

2.通过vue-cli创建vue项目(2/3都可以)

使用vue-cli脚手架创建,这个方法不支持vite

js 复制代码
vue create 项目名

3.添加vue自带的electron-builder

下面命令执行后会先执行vue脚手架再运行electron

js 复制代码
vue add electron-builder

4.打包exe程序

js 复制代码
npm run electron:build

注意,打包过程会下载各种东西,网络较差容易下载失败,给大家推荐一个好用的方法
在项目根目录下创建.npmrc文件,放入以下代码,这样下载的来源就是去淘宝镜像去下载,比较快

js 复制代码
ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron/
ELECTRON_BUILDER_BINARIES_MIRROR=http://npm.taobao.org/mirrors/electron-builder-binaries/

以上的解决网络慢问题来源于此

相关推荐
持续前行1 小时前
vscode 中找settings.json 配置
前端·javascript·vue.js
JosieBook2 小时前
【Vue】11 Vue技术——Vue 中的事件处理详解
前端·javascript·vue.js
安逸点2 小时前
Vue项目中使用xlsx库解析Excel文件
vue.js
一只小阿乐2 小时前
vue 改变查询参数的值
前端·javascript·vue.js·路由·router·网文·未花中文网
小酒星小杜3 小时前
在AI时代下,技术人应该学会构建自己的反Demo地狱系统
前端·vue.js·ai编程
Code知行合壹3 小时前
Pinia入门
vue.js
今天也要晒太阳4733 小时前
element表单和vxe表单联动校验的实现
vue.js
依赖_赖4 小时前
前端实现token无感刷新
前端·javascript·vue.js
hhcccchh5 小时前
学习vue第十三天 Vue3组件深入指南:组件的艺术与科学
javascript·vue.js·学习
zhengxianyi5155 小时前
ruoyi-vue-pro本地环境搭建(超级详细,带异常处理)
前端·vue.js·前后端分离·ruoyi-vue-pro