如何开发Vite3插件构建Electron开发环境

新用户购买《Electron + Vue 3 桌面应用开发》 , 加小册专属微信群,参与群抽奖,送《深入浅出Electron》、《Electron实战》作者签名版 。1等奖:《深入浅出Electron》+《Electron实战》2等奖:《深入浅出Electron》3等奖:《Electron实战》抽奖活动是掘金组织的 , 仅限近几日加入微信群的新成员(目前人还不多),我负责抽奖、邮寄,11月20日开始抽奖 。凡参与抽奖的读者都有机会中奖 。
开发新版本 Vue 项目推荐你使用 Vite 脚手架构建开发环境,然而 Vite 脚手架更倾向于构建纯 Web 页面,而不是桌面应用 , 因此开发者要做很多额外的配置和开发工作才能把 Electron 引入到 Vue 项目中 , 这也是很多开发者都基于开源工具来构建 Electron+Vue 的开发环境的原因 。
但这样做有两个问题:第一个是这些开源工具封装了很多技术细节,导致开发者想要修改某项配置非常不方便;另一个是这些开源工具的实现方式我认为也并不是很好 。
所以,我还是建议你尽量 自己写代码构建 Electron+Vue 的开发环境 ,这样可以让自己更从容地控制整个项目 。
具体应该怎么做呢?接下来我将带你按如下几个步骤构建一个 Vite+Electron 的开发环境:
如何开发Vite3插件构建Electron开发环境

文章插图
创建项目首先通过命令行创建一个 Vue 项目:
npm create vite@latest electron-jue-jin -- --template vue-ts接着安装 Electron 开发依赖:
npm install electron -D安装完成后,你的项目根目录下的 package.json 文件应该与下面大体类似:
{"name": "electron-jue-jin","private": true,"version": "0.0.1","scripts": {"dev": "vite","build": "vue-tsc --noEmit && vite build","preview": "vite preview"},"dependencies": {},"devDependencies": {"vue": "^3.2.37","@vitejs/plugin-vue": "^3.0.0","electron": "^19.0.8","typescript": "^4.6.4","vite": "^3.0.0","vue-tsc": "^0.38.4"}}注意:这里我们 把 vue 从 dependencies 配置节移至了 devDependencies 配置节 。这是因为在 Vite 编译项目的时候,Vue 库会被编译到输出目录下,输出目录下的内容是完整的,没必要把 Vue 标记为生产依赖;而且在我们将来制作安装包的时候,还要用到这个 package.json 文件,它的生产依赖里不应该有没用的东西 , 所以我们在这里做了一些调整 。
到这里,我们就创建了一个基本的 Vue+TypeScript 的项目 , 接下来我们就为这个项目引入 Electron 模块 。
创建主进程代码创建好项目之后,我们创建主进程的入口程序:src\main\mainEntry.ts 。
这个入口程序的代码很简单,如下所示:
//src\main\mainEntry.tsimport { app, BrowserWindow } from "electron";let mainWindow: BrowserWindow;app.whenReady().then(() => {mainWindow = new BrowserWindow({});mainWindow.loadURL(process.argv[2]);});在这段代码里,我们在 app ready 之后创建了一个简单的 BrowserWindow 对象 。app 是 Electron 的全局对象,用于控制整个应用程序的生命周期 。在 Electron 初始化完成后,app 对象的 ready 事件被触发,这里我们使用 app.whenReady() 这个 Promise 方法来等待 ready 事件的发生 。
mainWindow 被设置成一个全局变量 , 这样可以避免主窗口被 JavaScript 的垃圾回收器回收掉 。另外,窗口的所有配置都使用了默认的配置 。
这个窗口加载了一个 Url 路径,这个路径是以命令行参数的方式传递给应用程序的,而且是命令行的第三个参数 。
app 和 BrowserWindow 都是 Electron 的内置模块,这些内置模块是通过 ES Module 的形式导入进来的,我们知道 Electron 的内置模块都是通过 CJS Module 的形式导出的,这里之所以可以用 ES Module 导入,是因为我们接下来做的主进程编译工作帮我们完成了相关的转化工作 。
开发环境 Vite 插件主进程的代码写好之后,只有编译过之后才能被 Electron 加载,我们是 通过 Vite 插件的形式来完成这个编译工作和加载工作 的 , 如下代码所示:
//plugins\devPlugin.tsimport { ViteDevServer } from "vite";export let devPlugin = () => {return {name: "dev-plugin",configureServer(server: ViteDevServer) {require("esbuild").buildSync({entryPoints: ["./src/main/mainEntry.ts"],bundle: true,platform: "node",outfile: "./dist/mainEntry.js",external: ["electron"],});server.httpServer.once("listening", () => {let { spawn } = require("child_process");let addressInfo = server.httpServer.address();let httpAddress = `http://${addressInfo.address}:${addressInfo.port}`;let electronProcess = spawn(require("electron").toString(), ["./dist/mainEntry.js", httpAddress], {cwd: process.cwd(),stdio: "inherit",});electronProcess.on("close", () => {server.close();process.exit();});});},};};

推荐阅读