如何用Electron+vue+vite构建桌面端应用(一)

今年上半年主要是做 IM 桌面客户端项目的开发,主要用到的技术有 Electron+Vue+Vite,这里主要介绍下这个项目的构建过程方便下次快速创建类型项目。

用 vite 构建 vue3 项目

yarn create vite electron-vue-vite-template --template vue-ts
cd electron-vue-vite-template
yarn


至此一个简单的 vue3 项目已经搭建好

安装 Electron 并搭建基础架构

在安装 electron 之前我们先配置下下载源
在项目跟目录下新建.yarnrc 文件

registry=https://registry.npmmirror.com/
electron_mirror=https://npmmirror.com/mirrors/electron/

安装 electron

yarn add electron@19.0.8 -D

这里要说明下,因为我们开发的 IM 是要在国产银河麒麟上运行,而 electron 官网并没有提供麒麟系统 mips 架构的安装包,查询资料得知这里需要我们自己离线安装,详细内容可参考如何在国产银河麒麟系统 mips 架构上离线安装 electron

安装好 electron 后需要新建以下目录和文件:

mkdir electron && cd electron
mkdir main && cd main && touch index.ts
cd .. && mkdir preload && cd preload && touch index.ts

main 文件夹里的内容是 electron 主进程代码
preload 文件夹内容是预加载脚本
src 文件夹是渲染进程运行 web 网页

Electron 的主进程是一个具有完全操作系统访问权限的 Node.js 环境。在 Electron 模块之上,您还可以访问 Node.js 内置插件,以及通过 npm 安装的任何包。另一方面,渲染器进程运行网页并且出于安全原因默认不运行 Node.js。
为了将 Electron 的不同进程类型连接在一起,我们需要使用一个称为 preload 的特殊脚本。

编写 main/index.ts

import { app, BrowserWindow } from "electron";
import path, { join } from "path";

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, "../preload/index.js"),
    },
  });

  if (app.isPackaged) {
    win.loadFile(join(__dirname, "../../index.html"));
  } else {
    // 环境变量VITE_DEV_SERVER_HOST和VITE_DEV_SERVER_PORT在vite-plugin-electron插件中默认定义
    const url = `http://${process.env["VITE_DEV_SERVER_HOST"]}:${process.env["VITE_DEV_SERVER_PORT"]}`;

    win.loadURL(url);
  }
};

app.whenReady().then(() => {
  createWindow();

  app.on("activate", () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
  }
});

编写 preload/index.ts

import { contextBridge } from "electron";

contextBridge.exposeInMainWorld("versions", {
  node: () => process.versions.node,
  chrome: () => process.versions.chrome,
  electron: () => process.versions.electron,
});

这里将 versions 对象暴露给渲染进程

安装 electron 和 vite 相关包

yarn add electron-builder@23.1.0 vite-plugin-electron@0.7.5 -D

electron-builder 用于 electron 应用打包
vite-plugin-electron 方便用 vite 热更新 electron

编辑 vite.config.ts

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { join } from "path";
import electron from "vite-plugin-electron";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    electron({
      main: {
        entry: "electron/main/index.ts",
        vite: {
          build: {
            outDir: "dist/electron/main",
          },
        },
      },
      preload: {
        input: {
          // Must be use absolute path, this is the restrict of Rollup
          index: join(__dirname, "electron/preload/index.ts"),
        },
        vite: {
          build: {
            sourcemap: "inline",
            outDir: "dist/electron/preload",
          },
        },
      },
    }),
  ],
});

去掉 package.json 中"type":"module",因为项目中会用到 commonJS 类型包,增加"main":"dist/electron/main/index.js"项目入口

在 vite-env.d.ts 中增加 versions 对象申明

declare const versions: {
  node: () => string;
  chrome: () => string;
  electron: () => string;
};

在 App.vue 中加入以下下代码

<template>
 <p>
    app is using Chrome ({{ chrome }}), Node.js ({{ node }}), and Electron ({{
      electron
    }})
  </p>
</template>
<script setup lang="ts">
import { ref } from "vue";
const chrome = ref(versions.chrome());
const node = ref(versions.node());
const electron = ref(versions.electron());
</script>

执行 yarn dev 即可看到项目启动效果

热更新也正常

开始打包

修改 build 命令,加入 electron-builder 打包

"build": "vue-tsc --noEmit && vite build && electron-builder",

在根目录下新建 electron-builder.json5 文件

{
  "appId": "YourAppID",
  "asar": true,
  "directories": {
    "output": "release/${version}"
  },
  "files": ["dist"],
  "mac": {
    "artifactName": "${productName}_${version}.${ext}",
    "target": ["dmg"]
  },
  "win": {
    "target": [
      {
        "target": "nsis",
        "arch": ["x64"]
      }
    ],
    "artifactName": "${productName}_${version}.${ext}"
  },
  "nsis": {
    "oneClick": false, // 是否一键安装
    "perMachine": false,
    "allowToChangeInstallationDirectory": true, // 是否允许更改安装目录
    "deleteAppDataOnUninstall": false // 卸载是否删除AppData
  }
}

执行 yarn build 打包命令,执行完后可以在根目录下看到 release 文件夹里面有生成的 exe 可执行文件

注意
在打包过程中会从网上下载 electron,如果使用的 electron 版本较低 无法从镜像下载可以参考Electron 无法从淘宝镜像下载安装,报错 HTTPError Response code 404 (Not Found)的问题

至此,第一期一个简单的桌面客户端应用已经搭建完成,第二期继续完善 vue3 项目基础内容。

源码 Github 仓库:electron-vue-vite-template,如果觉得写得不错还希望给个小星星哦。