Vite+Vue3+TS+Electron构建桌面应用

Vite+Vue3+TS+Electron构建桌面应用_第1张图片

前言

之前开发项目遇到前端的需求,我通常会选择Vue2,无他,只是在众多前端框架中,我比较熟悉Vue2,此前尝试学过一段时间React,被它的Hook恶心到了,会了又学,学了又忘,所以还是回到Vue的怀抱,至于React,日后再挑战。

本篇文章使用当前最新的前端技术体系来构建一个桌面应用,本篇只是记录项目搭建的过程并实现项目的打包与安装,先看效果图:

Vite+Vue3+TS+Electron构建桌面应用_第2张图片 image.png

我们使用Vite来构建Vue3项目,看了Webpack与Vite在Dev阶段时,项目启动的速度,果断弃用复杂的Webpack,虽然Vite目前在生态上还差Webpack一段距离,但却会是后续的发展方向。

不熟悉Vite的可看Vite原理浅析

Vite构建Vue3项目

Vite对Vue3有较好的支持,直接使用vue-ts创建Vue3项目则可,然后使用TypeScript作为项目的开发语言。

yarn create vite vite-project --template vue-ts
cd vite-project
yarn
yarn dev

正常安装后,项目会在3000端口运行,访问locclhost:3000则可以看到Vite+Vue3+TS的项目

结合Electron

yarn add -D electron electron-builder

通过yarn安装electron与electron-builder(electron打包工具),因为国内的环境,我们可以使用.yarnrc或直接为yarn设置镜像,但这里需要注意一点,就是镜像网站的变更,npm淘宝源会在2022-05-31要切换镜像网站域名,之前的域名不再提供服务(https://zhuanlan.zhihu.com/p/432578145),那么之前很多博文里提及的设置镜像的文章日后就不再生效了。

最终我还是使用官方源配合科学上网来解决electron安装的问题,你也可以参考安装Electron门道安装Electron。

Vite在开发是会使用Koa作为Web服务来提高我们开发效率,也是因为Koa,我们才可以直接在开发过程中访问localhost:3000,但在正式上线时,Vite会将代码、资料打包成静态文件。

Electron在不引入Vite+Vue3时,可以直接通过朴素的HTML、CSS、JS来构建页面,Vite+Vue3的引入让我们要考虑如何让Electron在不同开发情况下接入Vite+Vue3,比如开发时,Electron载入localhost:3000,而打包后,Electron载入Vite打包后的静态文件。

为了实现上面的目的,需要安装一些npm包:

yarn add -D concurrently cross-env wait-on

其中,concurrently用于并行执行多个命令,wait-on用于实现命令间的广告,cross-env用于设置命令运行时的环境变量,安装完后,将package.json的scripts修改成如下形式:

"scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "serve": "vite preview",
    "electron": "wait-on tcp:3000 && cross-env IS_DEV=true electron .",
    "electron:dev": "concurrently -k \"cross-env BROWSER=none yarn dev\" \"yarn electron\"",
    "electron:builder": "electron-builder",
    "build:for:electron": "vue-tsc --noEmit && cross-env ELECTRON=true vite build",
    "app:build": "yarn build:for:electron && yarn electron:builder"
  },

开发时,通过yarn electron:dev启动electron项目,electron:dev指令会通过concurrently并行执行yarn dev与yarn electron,其中运行yarn dev时,通过cross-env设置了此次命令的环境变量,这里将BROWSER环境变量设置为none,这样vite就不会主动通过浏览器打开localhost:3000(但我们可以主动访问这个页面)。

yarn dev命令会运行vite服务,yarn electron会运行electron服务,该命令首先会通过wait-on等等3000端口的服务启动后再执行electron .,而3000端口正是vite服务默认启动的端口,如果vite启动服务时,发现3000端口被占有,会默认使用3001,此时yarn electron也需要相应的修改调整。

光在package.json的scripts中指定各种指令是没用的,还需要让npm指定入口文件,在package.json中设置main:

"main": "electron/electron.js",

然后再vite-project目录下创建electron文件夹,然后再文件夹中创建electron.js文件,在js文件中,使用electron创建桌面应用的窗口,代码如下:

const path = require('path');
const { app, BrowserWindow } = require('electron');

// 判断环境变量
const isDev = process.env.IS_DEV == "true" ? true : false;

function createWindow() {
  // 创建窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      // 预加载
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: true,
    },
  });

  // 基于环境变量,判断窗口要载入的内容(即要显示的内容)
  mainWindow.loadURL(
    isDev
      ? 'http://localhost:3000'  // 如果是开发环境,则载入vite服务
      : `file://${path.join(__dirname, '../dist/index.html')}`  // 如果是正式环境,则载入vite生成的index.html
  );
  // 如果是开发环境,则自动打开Chrome debugger工具
  if (isDev) {
    mainWindow.webContents.openDevTools();
  }
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  
  createWindow()
  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
});

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

electorn.js中主要的逻辑就是通过isDev环境变量判断要载入的内容,此外就是给app对象设置相应的监听回调函数,这块主要兼容MacOS环境下的情况,不赘述。但Electron预加载(preload)的功能可以聊一下。

上述代码中,通过webPreferences.preload属性,我们预加载了preload.js,该文件代码如下:

// 所有Node.JS API都可以使用
// 拥有与Chrome插件一样的沙箱(sandbox)环境
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])
    }
  })

我们这里的preload.js虽然没做啥,但利用Electron preload我们可以做很多有趣的事情,有必要展开聊聊。

Electron preload

preload在Electron中不是新鲜事物,3.0版本就支持了,但因为早期的Electron在渲染进程(renderer)中可以直接使用Node.JS的API,preload就没太被关注,但在5.x以后,Electron渲染进程中默认不可以使用Node了,虽然可以通过配置打开对Node API的支持,但社区的态度慢慢转向禁用node,从而避免网页JS恶意使用Node的情况。

比如你开发的Electron具有访问互联网中网页的功能,如果渲染进程开启了Node,恶意网页中的JS就可以利用NodeJS直接对你的系统进行操作,这是非常危险的。

在对安全的考虑下,Electron官方不建议在渲染进程中开启Node API的支持,而是建议使用preload,Electron在渲染每个页面前都会执行preload指定的JS脚本,上述例子就是执行preload.js。

Electron让preload指定的JS脚本拥有早于网页JS执行的能力,且preload可以使用NodeJS,再加上它拥有Chrome插件一般的沙箱,利用Electron去访问第三方访问,再基于preload的能力去魔改这些网页的JS就是一条不错的路子(没错,可以往爬虫方向靠)。

完善package.json

编写好electron.js、preload.js以及package.json的main和scripts后,便可以在开发状态下运行electron项目了:

yarn electron:dev
Vite+Vue3+TS+Electron构建桌面应用_第3张图片

当我们编写完业务逻辑后,需要打包出不同系统平台的应用,然后分发给用户,此时我们需要使用electron-builder,在package.json中添加如下内容:

"build": {
    "appId": "com.my-website.my-app",
    "productName": "MyApp",
    "copyright": "Copyright © 2019 ${author}",
    "mac": {
      "category": "public.app-category.utilities"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "directories": {
      "buildResources": "assets",
      "output": "dist_electron"
    }
  }

上面都是electron-builder的基本配置,可以参考:https://www.electron.build/configuration/configuration

配置好后,通过yarn app:build便可以打包应用了。Vite+Vue3+TS+Electron构建桌面应用_第4张图片

主要观察输出内容,打包应用时会从github中下载相应的资源,如果你没有科学上网,这里很容易识别,如果你跟我一样使用windows的powershell,可以通过下面方式,对powershell命令行设置代理:

$env:http_proxy="http://127.0.0.1:1080"
$env:https_proxy="http://127.0.0.1:1080"

完成打包后,安装到windows中,双击运行,得到本文首图的效果Vite+Vue3+TS+Electron构建桌面应用_第5张图片

结尾

清明节3天假期到啦,又可以长时间编自己的程序了,搓搓手,趁着假期,将RPA软件的基本的Demo写出来吧,Enjoy Code!下篇文章见。

你可能感兴趣的:(vue,java,js,javascript,web)