eletron开发

1.安装

npm i electron electron-builder -D

2.编写electron主进程文件

// 主进程文件
import { app, BrowserWindow } from 'electron'

app.whenReady().then(() => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      // 可以在渲染进程中使用node的api,为了安全考虑,一般关闭
      nodeIntegration: true,
      // 关闭渲染进程的沙箱,防止进程中的npm包被注入木马
      contextIsolation: false,
      // 关闭跨域检测
      webSecurity: false
    }
  })
  // win.webContents.openDevTools()
  // 获取在vite.electron.dev.ts中在进程传的参数
  if (process.argv[2]) {
    win.loadURL(process.argv[2])
  } else {
    win.loadFile('index.html')
  }
})

2.编写开发环境和生产环境的插件

import type { Plugin } from "vite"
import fs from 'node:fs'
import path from "node:path"
import * as electronBuilder from 'electron-builder'
const buildBackground = () => {
  // 把ts文件编译成js文件
  require('esbuild').buildSync({
    entryPoints: ['src/background.ts'], // 指定文件
    bundle: true, // 打包
    outfile: 'dist/background.js', // 输出文件地址
    platform: 'node', // 指定平台
    target: 'node12', // 指定node版本
    external: ['electron'], // 不打包electron
  })
}

// 因为background的线上打包执行win.loadFile('index.html')
// 所以需要先npm run build执行完才会有index.html
export const electronBuildPlugin = ():Plugin => {
  return {
    name: 'electron-build',
    // vite的插件生命周期钩子,closeBundle是vite执行打包完后的生命收起
    // 因为需要先产生index.html,所以需要在closeBundle生命周期
    closeBundle() {
      buildBackground()
      // electron-builder 需要指定package.json main
      // 使用fs把package.json读成utf-8格式,然后转成json
      const json = JSON.parse(fs.readFileSync('package.json', 'utf-8'))
      json.main = 'background.js'
      fs.writeFileSync('dist/package.json',JSON.stringify(json,null,4))
      // 兼容electron-builder会给你下载垃圾文件,解决bug
      fs.mkdirSync('dist/node_modules')

      electronBuilder.build({
        config:{
          directories: {
            // 指定输出路径,cwd指的是根路径
            output: path.resolve(process.cwd(),'release'),
            // 指定根据dist下的文件来打包
            app: path.resolve(process.cwd(),'dist')
          },
          asar: false, // 会打包成压缩包,提高打包效率
          appId: 'demo', // 打包需要指定真实的appid,
          productName: 'pName', // 指定名称
          // 安装时候的设置
          nsis: {
            oneClick: false, // 取消一键安装
            // 允许用户指定路径安装
            allowToChangeInstallationDirectory: true
          }
        }
      })
    }
  }
}
import type { Plugin } from "vite"
import type { AddressInfo } from "node:net"
// 可以返回进程的信息
import { spawn } from "node:child_process"
import fs from "node:fs"

const buildBackground = () => {
  // 把ts文件编译成js文件
  require('esbuild').buildSync({
    entryPoints: ['src/background.ts'], // 指定文件
    bundle: true, // 打包
    outfile: 'dist/background.js', // 输出文件地址
    platform: 'node', // 指定平台
    target: 'node12', // 指定node版本
    external: ['electron'], // 不打包electron
  })
}
// vite插件需要返回一个对象,必要要有name属性
export const electronPlugin = (): Plugin => {
  return {
    name: 'electron-dev',
    // vite的插件生命周期钩子,configureServer是在vite启动时调用的
    // 通过这个钩子在启动的时候启动electron
    configureServer(server) {
      buildBackground()
      server?.httpServer?.on('listening', () => {
        // 获取服务的地址信息
        const addressInfo = server?.httpServer?.address() as AddressInfo
        // 拼接IP信息
        const IP = `http://localhost:${addressInfo.port}`
        // 启动electron进程
        // 第一个参数是electron的路径
        // require('electron')返回的是一个路径
        // 第二个参数是启动的文件: 不识别ts文件,所以需要编译成js文件
        // 第三个参数是传递的参数
        // 把信息传递给electron进程,'dist/background.js'参数1;IP参数2
        let ElectronProcess = spawn(require('electron'), ['dist/background.js', IP])
        // 热更新,监听文件
        fs.watchFile('src/background.ts', () => {
          // 每次有更新就会杀死前一个进程,否则会一直开进程
          ElectronProcess.kill()
          buildBackground()
          ElectronProcess = spawn(require('electron'), ['dist/background.js', IP])
        })
        // 日志监控
        ElectronProcess.stderr.on('data', (data) => {
          console.log('日志',data.toString());
        })
      })
    }
  }
}

3.mian文件引入插件

import { fileURLToPath, URL } from 'node:url'
// loadEnv
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { electronPlugin } from './plugins/vite.electron.dev.ts'
import { electronBuildPlugin } from './plugins/vite.electron.build.ts'
// https://vitejs.dev/config/
export default defineConfig((config) => {
  const {
    mode, // 当前环境
    command // 当前命令 npm run serve 中的serve 用来区分 build or serve
    // ssrBuild, // 是否是 ssr 构建
  } = config
  const proxy = {
    // largeScreenProxy: 'https://www.patyee.com'
    largeScreenProxy: 'http://121.37.233.37:8089'
  }
  return {
    base: './', // 默认是绝对路径,改成相对路径
    plugins: [vue(), vueJsx(), electronPlugin(),electronBuildPlugin()],
    server: {
      host: '0.0.0.0',
      proxy: {
        '/largeScreen': {
          target: proxy.largeScreenProxy,
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/largeScreen/, 'ourchem-middle')
        }
      }
    },
    define: {
      'process.env': {
        NODE_ENV: mode,
        NODE_COMMAND: command
      },
      __CRYPTOJSKEY__: "'88Uv*RT@ReLhg~PV'"
    },
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url))
      }
    },
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `
            @import "@/assets/_variables.scss";
            @import "@/assets/_mixins.scss";  
          ` // 引入全局变量
        }
      }
    }
  }
})

 

posted on 2025-03-13 23:16  ChoZ  阅读(33)  评论(0)    收藏  举报

导航