vue3 ts vite electron开发桌面程序

1、搭建vue+ts+vite项目

创建Vue项目

npm init vue

安装依赖

npm install

一定要安装成开发依赖

npm install electron electron-builder -D

根目录创建plugins文件夹,文件夹中创建ts文件,vite.electron.build.ts是打包文件代码,vite.electron.dev.ts是开发环境代码

vite.electron.build.ts代码

复制代码
// 打包electron项目
import type { Plugin } from "vite";
import * as electronBuilder from "electron-builder";
import path from "path";
import fs from "fs";
import { createRequire } from 'module';

const require = createRequire(import.meta.url);

// 导出Vite插件函数
export const viteElectronBuild = (): Plugin => {
  return {
    name: "vite-electron-build",

    // closeBundle是Vite的一个插件钩子函数,用于在Vite构建完成后执行一些自定义逻辑。
    closeBundle() {
      // 定义初始化Electron的函数
      const initElectron = () => {
        // 使用esbuild编译TypeScript代码为JavaScript
        require("esbuild").buildSync({
          entryPoints: ["src/background.ts"],
          bundle: true,
          outfile: "dist/background.js",
          platform: "node",
          target: "node12",
          external: ["electron"],
        });
      };

      // 调用初始化Electron函数
      initElectron();

      // 修改package.json文件的main字段 不然会打包失败
      const json = JSON.parse(fs.readFileSync("package.json", "utf-8"));
      json.main = "background.js";
      fs.writeSync(
        fs.openSync("dist/package.json", "w"),
        JSON.stringify(json, null, 2)
      );

      // 创建一个空的node_modules目录 不然会打包失败
      fs.mkdirSync(path.resolve(process.cwd(), "dist/node_modules"));

      // 使用electron-builder打包Electron应用程序
      electronBuilder.build({
        config: {
          appId: "com.example.app",
          productName: "vite-electron",
          directories: {
            output: path.resolve(process.cwd(), "release"), // 输出目录
            app: path.resolve(process.cwd(), "dist"), // app目录
          },
          asar: true,
          nsis: {
            oneClick: false, // 取消一键安装
            allowToChangeInstallationDirectory: true // 选择安装目录
          },
        },
      });
    },
  };
};

vite.electron.dev.ts代码

复制代码
// 编写electron开发模式
import type { Plugin } from "vite";
import type { AddressInfo } from "net";
import { spawn } from "child_process";
import fs from "node:fs";
import { createRequire } from 'module';

const require = createRequire(import.meta.url);

// 导出vite插件函数
export const viteElectronDev = (): Plugin => {
  return {
    name: "vite-electron-dev",
    // 在configureServer中实现插件的逻辑
    configureServer(server) {
      // 定义初始化Electron的函数
      const initElectron = () => {
        // 使用esbuild编译TypeScript代码为JavaScript
        require("esbuild").buildSync({
          entryPoints: ["src/background.ts"],
          bundle: true,
          outfile: "dist/background.js",
          platform: "node",
          target: "node12",
          external: ["electron"],
        });
      };

      // 调用初始化Electron函数
      initElectron();

      // 监听Vite的HTTP服务器的listening事件
      server?.httpServer?.once("listening", () => {
        // 获取HTTP服务器的监听地址和端口号
        const addressInfo = server?.httpServer?.address() as AddressInfo;
        const IP = `http://localhost:${addressInfo.port}`;
        // 启动Electron进程
        let electronProcess = spawn(require("electron"), [
          "dist/background.js",
          IP,
        ]);

        // 监听主进程代码的更改
        fs.watchFile("src/background.ts", () => { 
          // 杀死当前的Electron进程
          electronProcess.kill();
          // 重新编译主进程代码并重新启动Electron进程
          initElectron();
          electronProcess = spawn(require("electron"), [
            "dist/background.js",
            IP,
          ]);
        });

        // 监听Electron进程的stdout输出
        electronProcess.stderr?.on("data", (data) => {
          console.log(`日志:${data}`);
        })
      })
    }
  }
}

在src目录下创建background.ts文件

background.ts代码

复制代码
import { app, BrowserWindow } from 'electron'

// 等待Electron应用就绪后创建BrowserWindow窗口
app.whenReady().then(async () => {
    const win = await new BrowserWindow({
        width: 800,
        height: 600,

        // 配置窗口的WebPreferences选项,用于控制渲染进程的行为
        webPreferences: {
            nodeIntegration: true, // 启用Node.js集成
            contextIsolation: false, // 禁用上下文隔离
            webSecurity: false, // 禁用web安全策略
        }
    })
    console.log('----------123-------');
        console.log(process);
    // 根据命令行参数加载URL或本地文件
    if (process.argv[2]) {
        win.loadURL(process.argv[2])
    } else {
        win.loadFile('index.html')
    }
})

vite.config.ts导入文件,添加base:'./'

在tsconfig.node.json添加plugins文件夹下ts文件的提示

至此,就可以运行electron项目了;

运行时错误信息:

解决办法:

是因为node13版本以后会使用es module,在package.json中,type改为commonjs即可

相关推荐
kyriewen116 小时前
你点的“刷新”是假刷新?前端路由的瞒天过海术
开发语言·前端·javascript·ecmascript·html5
摇滚侠7 小时前
JAVA 项目教程《苍穹外卖-12》,微信小程序项目,前后端分离,从开发到部署
java·开发语言·vue.js·node.js
Timer@7 小时前
LangChain 教程 04|Agent 详解:让 AI 学会“自己干活“
javascript·人工智能·langchain
阿珊和她的猫8 小时前
TypeScript中的never类型: 深入理解never类型的使用场景和特点
javascript·typescript·状态模式
九皇叔叔12 小时前
003-SpringSecurity-Demo 统一响应类
java·javascript·spring·springsecurity
低代码布道师13 小时前
纯代码实战:MBA培训管理系统 (十四) ——用户管理(批量选择与批量删除)
javascript·nextjs
打瞌睡的朱尤13 小时前
建立vue项目
vue.js
Hello--_--World14 小时前
JavaScript运行机制、v8原理、js事件循环
开发语言·javascript·ecmascript
bearpping15 小时前
Spring Boot + Vue 全栈开发实战指南
vue.js·spring boot·后端
敲敲了个代码17 小时前
React 那么多状态管理库,到底选哪个?如果非要焊死一个呢?这篇文章解决你的选择困难症
前端·javascript·学习·react.js·前端框架