【前端记事】关于electron的入门使用

electron入门使用

背景

最近对electron比较感兴趣,折腾一段时间后有了点眉目,记录一下

how to start

第一步 创建一个vite-vue3项目

bash 复制代码
# 选vue3但是不要用ts,用js会舒服得多
npm create vite -n test-electron

第二步 装各种依赖

bash 复制代码
# 命令1
npm i electron -d -s
# 命令2
npm install vite-plugin-optimizer --save-dev
# 命令3
npm install vite-plugin-node-polyfills --save-dev
# 命令4
npm install @electron/remote
# 命令5
npm install element-plus --save
# 命令6
npm i vue-router

注意,命令1可能需要反复执行反复失败才会成功,推测是网的原因,而且我自己测试用yarn和pnpm必报错,只有npm才行

第三步 配置

vite.config.js

js 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
import optimizer from 'vite-plugin-optimizer'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(), // 添加 Node.js 内置模块的 polyfill
    nodePolyfills({
      include: ['path'],
      globals: { Buffer: true, global: true, process: true },
      protocolImports: true,
    }),
    optimizer({
      electron: `const { ipcRenderer } = require('electron'); export { ipcRenderer };`
    })
  ],
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          // 将第三方库分割到单独的代码块
          'vendor': ['element-plus'],
        }
      }
    }
  },
  server: {
    port: 8888,
    cors: true, // 允许跨域
    hmr: true, // 开启热更新
  },
  "base": "./"
})

package.json

json 复制代码
{
  "name": "ele-pro",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "main": "electron/main.cjs",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron:serve": "vite build && electron ."
  },
  "dependencies": {
    "@electron/remote": "^2.1.2",
    "electron-reload": "^2.0.0-alpha.1",
    "element-plus": "^2.9.7",
    "vue": "^3.5.13",
    "vue-router": "^4.5.0"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.2.1",
    "electron": "^35.1.3",
    "vite": "^6.2.0",
    "vite-plugin-node-polyfills": "^0.23.0",
    "vite-plugin-optimizer": "^1.4.3"
  }
}

一定要重点关注入口:"main": "electron/main.cjs",和electron启动命令:"electron:serve": "vite build && electron ."

electron入口

在项目的根目录下新建文件夹/electron。

在文件夹中新建文件main.cjs

注意,一定要是.cjs,不是.js

js 复制代码
// 控制应用生命周期和创建原生浏览器窗口的模组
const { app, BrowserWindow, Menu } = require('electron')
const path = require('path')
require('@electron/remote/main').initialize()

function createWindow() {
  // 创建浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    frame: false, // 隐藏默认的标题栏
    webPreferences: {
      // 书写渲染进程中的配置
      nodeIntegration: true, //开启true这一步很重要,目的是为了vue文件中可以引入node和electron相关的API
      contextIsolation: false, // 可以使用require方法
    },
  })
  require('@electron/remote/main').enable(mainWindow.webContents)

  let env = 'pro'
  // 配置热更新
  if (env == 'pro') {
    const elePath = path.join(__dirname, '../node_modules/electron')
    require('electron-reload')('../', {
      electron: require(elePath),
    })
    // 热更新监听窗口
    mainWindow.loadURL('http://localhost:8888')
    // 打开开发工具
    mainWindow.webContents.openDevTools()
  } else {
    // 生产环境中要加载文件,打包的版本
    // Menu.setApplicationMenu(null)
    // 加载 index.html
    mainWindow.loadFile(path.resolve(__dirname, '../dist/index.html')) // 新增
  }
}
// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
  // 关闭默认菜单栏
  Menu.setApplicationMenu(null)
  createWindow()

  app.on('activate', function () {
    // 通常在 macOS 上,当点击 dock 中的应用程序图标时,如果没有其他
    // 打开的窗口,那么程序会重新创建一个窗口。
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 因此,通常对程序和它们在
// 任务栏上的图标来说,应当保持活跃状态,直到用户使用 Cmd + Q 退出。
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})

启动

打开两个终端窗口,需要都在该项目的根目录。

先运行npm run dev

再运行npm run electron:serve

这样,electron就能根据vue的内容实时渲染

重写关闭、隐藏、最大化最小化

在vue的根组件App.vue中:

html 复制代码
<script setup>
import {
  Close,
  FullScreen,
  ArrowDown
} from '@element-plus/icons-vue'
import { getCurrentWindow } from '@electron/remote'
// 关闭
const closeApp = () => {
  const currentWindow = getCurrentWindow()
  currentWindow.close()
}
// 全屏/退出全屏应用
const fullScreenApp = () => {
  const currentWindow = getCurrentWindow()
  if (currentWindow.isFullScreen()) {
    currentWindow.setFullScreen(false)
  } else {
    currentWindow.setFullScreen(true)
  }
}

// 最小化应用
const hideApp = () => {
  const currentWindow = getCurrentWindow()
  currentWindow.minimize()
}
</script>

<template>
  <div>
    <div style="padding: 10pt; text-align: right;">
      <el-button type="warning" size="small" circle :icon="ArrowDown" @click="hideApp"></el-button>
      <el-button type="success" size="small" :icon="FullScreen" circle @click="fullScreenApp" />
      <el-button type="danger" size="small" :icon="Close" circle @click="closeApp" />
    </div>
    <router-view></router-view>
  </div>
</template>

<style scoped>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  color: #2c3e50;
}
</style>

先到这里,后面有什么好玩的继续更新

相关推荐
隐形喷火龙8 分钟前
搭建TypeScript单元测试环境
javascript·typescript·单元测试
fs哆哆14 分钟前
在VB.net和VBA中,自定义函数GetTargetSheet()返回工作表对象
java·开发语言·前端·javascript·ecmascript
好_快25 分钟前
Lodash源码阅读-uniqBy
前端·javascript·源码阅读
好_快29 分钟前
Lodash源码阅读-uniqWith
前端·javascript·源码阅读
恋猫de小郭1 小时前
Flutter Widget IDE 预览新进展,开始推进落地发布
android·前端·flutter
jingling5552 小时前
【Vue3 实战】插槽封装与懒加载
前端·javascript·vue.js
Freedom风间7 小时前
前端优秀编码技巧
前端·javascript·代码规范
萌萌哒草头将军8 小时前
🚀🚀🚀 Openapi:全栈开发神器,0代码写后端!
前端·javascript·next.js
萌萌哒草头将军8 小时前
🚀🚀🚀 Prisma 爱之初体验:一款非常棒的 ORM 工具库
前端·javascript·orm
拉不动的猪8 小时前
SDK与API简单对比
前端·javascript·面试