新星计划 Electron+vue2 桌面应用 1 基础

/(ㄒoㄒ)/~~报名了两个新星计划,工作之余写博客……

另外一个是uniapp的属于个人兴趣,这个桌面应用正好符合工作需要。

活动地址:https://marketing.csdn.net/p/1738cda78d47b2ebb920916aab7c3584

教程地址:

2023新星导师活动【electron+vue3】方向,开营知识点提纲(1)_中二少年学编程的博客-CSDN博客

快速入门 | Electron

之前用uniapp做h5,再用Electron做确实编译出一个exe文件,但之后领导并没有把这个需求让我实现,嗯……所以并没有深入研究,这回也是简单学习下。

vue2文档地址:Vue.js

electron文档地址:简介 | Electron

 vue2有点基础,所以跳过。

1、Electron

Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架,嵌入Chromium和Node.js。

开发时,本地必须安装Node.js。

Electron 将 Node.js 嵌入到其二进制文件中,应用运行时的 Node.js 版本与系统中运行的 Node.js 版本无关。

//创建应用
npm init
npm install --save-dev electron
//或者 npm install -g electron  全局安装
//运行
npm start
//编译 百度后的结果 试过之后确实编译成功 并可正常运行编译结果
electron-packager . 
    应用名 
    --platform=win32 
    --electron-version=10.0.0 
    --arch=x64 
    --download.mirrorOptions.mirror=https://npm.taobao.org/mirrors/electron/ 
    --asar 
    --app-version=0.0.0 
    --build-version=0.0.0 
    --out=输出文件名字 
    --overwrite 
    --no-package-manager 
    --ignore="(.git)" 
    --icon=ico图标文件

编译设置

https://npm.taobao.org/mirrors/electron/

是为了加快编译速度,electron-version要和上述网址中的内容对应,不然报错。

第一次编译的时候写成:electron-version=1.0.0,大概是报错这个版本找不到。

官方给的样例为:GitHub - electron/electron-quick-start: Clone to try a simple Electron app

2、Electron Forge

用过vue的大概都知道,vue的脚手架的使用方法,electron有个类似的electron forge。

Electron Forge 官网:Getting Started - Electron Forge

//安装 未安装的情况
cd 项目
npm install --save-dev @electron-forge/cli
npx electron-forge import
//安装依赖
npm install --save-dev @electron-forge/cli 
    @electron-forge/maker-squirrel 
    @electron-forge/maker-deb 
    @electron-forge/maker-zip
//创建项目
npm init electron-app@lastest myapp
//使用模板
npm init electron-app@lastest myapp2 
    --
    --template=webpack//可选 webpack 和 webpack-typescript
//启动
cd 项目名
npm start
//编译
npm run make

 

另外说一句,Node.js新版npm操作后直接写入package.json,--save这种写法貌似是针对旧版不写入package.json中。

官方建议做windows app的时候,建议安装electron-squirrel-startup。

//安装
cd my-app
npm install electron-squirrel-startup
//使用 mian.js中处理
if (require('electron-squirrel-startup')) 
app.quit();

官网上有其配置和cli的详细解说,都是纯英文的,/(ㄒoㄒ)/~~ 能力有限就不翻译了。

看官网教程,还贴心的具体指出nodejs的官方文档  :Introduction to Node.js

3、 预加载

Electron 的主进程是一个拥有着完全操作系统访问权限的 Node.js 环境,渲染进程跑在网页中,

为了将 Electron 的不同类型的进程桥接在一起,需要使用被称为 预加载 的特殊脚本。

preload.js为预加载脚本。

BrowserWindow 的预加载脚本运行在具有 HTML DOM 和 Node.js、Electron API 的有限子集访问权限的环境中。

从 Electron 20 开始,预加载脚本默认 沙盒化 ,不再拥有完整 Node.js 环境的访问权,意味着只拥有一个 polyfilled 的 require 函数,这个函数只能访问一组有限的 API。

新星计划 Electron+vue2 桌面应用 1 基础_第1张图片

//preload.js 内容
const { contextBridge } = require('electron')

contextBridge.exposeInMainWorld('versions', {
  node: () => process.versions.node,
  chrome: () => process.versions.chrome,
  electron: () => process.versions.electron,
  // 能暴露的不仅仅是函数,我们还可以暴露变量
})


//加载 main.js
const { app, BrowserWindow } = require('electron')
const path = require('path')

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

  win.loadFile('index.html')
}

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

 _dirname字符串指向当前正在执行的脚本的路径,上面应该是根路径。

path.join是Node.js提供的api:Path | Node.js v20.2.0 Documentation

4、进程间通信

既然是多进程嘛,就涉及进程之间通信问题。

IPC指进程之间通信,可以使用 Electron 的 ipcMain 模块和 ipcRenderer 模块来进行进程间通信

 为了从网页向主进程发送消息,使用 ipcMain.handle 设置一个主进程处理程序(handler),然后在预处理脚本中暴露一个被称为 ipcRenderer.invoke 的函数来触发该处理程序(handler)。

//preload.js 暴露函数
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('versions', {
  node: () => process.versions.node,
  chrome: () => process.versions.chrome,
  electron: () => process.versions.electron,
  ping: () => ipcRenderer.invoke('ping'),
  // 能暴露的不仅仅是函数,我们还可以暴露变量
})


//main.js 函数定义
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  })
  ipcMain.handle('ping', () => 'pong')
  win.loadFile('index.html')
}
app.whenReady().then(createWindow)

//index.html


  
    
    
    
    来自 Electron 渲染器的问好!
  
  
    

来自 Electron 渲染器的问好!

//renderer.js 使用函数 index.html里包含并运行这个文件 const func = async () => { const response = await window.versions.ping() console.log(response) // 打印 'pong' } func()

根据上面例子,运行起来的话控制台应该打印pong。总体来讲,就是监听、注册、运行。

根据官网,暴露的时候使用ipcRenderer.invoke('ping'),而不直接暴露ipcRenderer,因为ipcRenderer直接暴露会导致渲染器能够直接向主进程发送任意的 IPC 信息,会使得其成为恶意代码最强有力的攻击媒介。

在主进程中设置监听器在主进程中需要保证加载完后运行。

官网专门讲进程通信:进程间通信 | Electron

根据上一行官网内容,发现还有其他方法做交互。

语境隔离(Context Isolation)意味着预加载脚本与渲染器的主要运行环境是隔离开来的,以避免泄漏任何具特权的 API 到您的网页内容代码中。我们將使用 contextBridge 模块来安全地实现交互。

//preload.js
const { contextBridge } = require('electron')

contextBridge.exposeInMainWorld('myAPI', {
  desktop: true,
})


//renderer.js
const func = async () => {
  console.log(window.myAPI)//打印{ desktop: true }
}
func()

官网解释utilityProcess为效率进程,用于主进程调用子进程,也有一套子进程通讯的api。

官网地址:

utilityProcess | Electron

MessagePortMain | Electron

// 主进程
const { port1, port2 } = new MessageChannelMain()
//utilityProcess.fork(子进程入口)
const child = utilityProcess.fork(path.join(__dirname, 'test.js'))
//postmessage 参数: 1、数据 2、MessagePortMain[] 数据可选 数据大概是端口
//根据文档第二个参数用于权限转移 数据大概是端口
//child大概是个MessagePortMain对象
child.postMessage({ message: 'hello' }, [port1])

// Child process
process.parentPort.once('message', (e) => {
  const [port] = e.ports
})

你可能感兴趣的:(前端,electron,javascript,前端)