跳到主要内容

· 阅读需 3 分钟

之前是使用React、Electron、TS和webpack来构建桌面应用的。虽然功能齐全,但是打包等等开发的体验不太理想,总感觉太慢了。作为一个开发者,我们总是希望,执行构建命令后,可以快速打包或者启动本地应用,且通过更少的配置,来完成开发体验。

现在的vite已经得到广泛的应用。

同样配置,vite启动和打包应用的速度,远远快于webpack。因此我体验一下vite、vue3和Electron的组合,看看能够带来什么样的体验。

这里所有的依赖包都是最新版本。

1、先创建一个vue3的应用。执行命令:npm create vite@ vue_electron --template vue-ts,如下图所示: 在这里插入图片描述 选择对应的框架和语言即可然后一直回车,这样就成功创建了vue应用。

2、下载安装electron、已经electron相关的依赖,比如electron-builder。在下载electron,一搬会出现很慢,甚至是卡顿的现象。我找了国内相关的镜像设置,只有这个是最有效的:

registry=https://mirrors.huaweicloud.com/repository/npm/
electron_mirror=https://npm.taobao.org/mirrors/electron/

下载也很快。

3、再下载vite和electron相关的插件:

vite-plugin-electron
vite-plugin-electron-renderer

很多插件的作用就是为了方便开发者工作,提升效率,获取更好的开发体验。

现在开始配置:

1、在应用的根目录创建electron-main和electron-preload目录,其中electron-main是存放主进程的文件,比如:index.ts;electron-preload文件夹存放的是electron需要加载的其他js文件。

2、在主进程文件index.ts创建electron窗口:代码如下:

import {app, BrowserWindow} from "electron/electron"
import path from "path";

const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, './preload.js'),
nodeIntegration: true, // 渲染进程使用Node API
contextIsolation: true, // 是否隔离上下文
}
})
// 加载vue url视本地环境而定,如http://localhost:5173
// win.loadURL('http://localhost:3000')
if (process.env.NODE_ENV === 'development') {
win.loadURL('http://localhost:5173')
win.webContents.openDevTools()
} else {
win.loadFile(path.join(__dirname, './index.html'))
}
}

app.whenReady().then(() => {
createWindow(); // 创建窗口
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})

// 关闭窗口
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})

在package.json文件里面,配置启动和打包应用的命令,

  "scripts": {
"dev": "vite",
"build": "rimraf dist-electron vue-tsc && vite build",
"preview": "vite preview",
"electron:dev": "concurrently \"yarn dev\" && \"electron .\"",
"electron:build": "yarn build && electron-builder"
},

这就是electron结合vue3和vite的基本配置。

· 阅读需 3 分钟

在安装 Electron 的时候,因为访问的是国外的 IP,所以很容安装失败,需要设置访问国内的 Electron 镜像: yarn config set ELECTRON_MIRROR http://cdn.npm.taobao.org/dist/electron/

安装 ELectron:yarn add electron --dev --platform=win64

在 package.json 文件中设置:

{
"name": "electron",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "electron ./index.js"
},
"devDependencies": {
"electron": "^16.0.7"
}
}

然后在项目目录下创建 index.js 和 index.html:

index.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>djdfj</title>
<link rel="stylesheet" type="text/css" href="./index.css"/>
</head>

<body>
<h1>Hello World!哈哈哈</h1>
We are using Node.js <span id="node-version"></span>, Chromium
<span id="chrome-version"></span>, and Electron
<span id="electron-version"></span>.
<p>Current theme source: <strong id="theme-source">System</strong></p>

<button id="toggle-dark-mode">Toggle Dark Mode</button>
<button id="reset-to-system">Reset to System Theme</button>

<button id="openDevTool">打开开发工具</button>
<script src="renderer.js"></script>
<script>
let {remote} = require("electron/electron");
console.log("remote", remote);
document.querySelector("#openDevTool").addEventListener("click", () => {
remote.getCurrentWindow().webContents.openDevTool();
});
</script>
</body>
</html>

index.js:

const {app, BrowserWindow, ipcMain, nativeTheme} = require("electron/electron");
const path = require("path");

function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
nodeIntegration: true,
},
});

win.loadFile("index.html");
ipcMain.handle("dark-mode:toggle", () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = "light";
} else {
nativeTheme.themeSource = "dark";
}
return nativeTheme.shouldUseDarkColors;
});

ipcMain.handle("dark-mode:system", () => {
nativeTheme.themeSource = "system";
});
}

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

app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});

app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});

执行命令:yarn start:效果如图

在这里插入图片描述

在 Electron 内部已经集成了 nodejs,所以我们直接引入 electron 的模块即可。

app 表示是整个应用,通过 app 可以调用应用程序的各个事件。

BrowserWindow,负责创建和管理应用的窗口。

如上面的代码中,在创建窗口的时候,设置了窗口的默认宽高以及 webPreferences,

webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration:true
}

这一项配置是给 Electron 页面继承 nodenode 环境,并且让 index.html 页面的 JavaScript 拥有访问 node 的能力。

如果我们加载的页面是一个网络页面,但是我们不能确保该页面是否可靠,那么 nodeIntegration 可以设置为 false,不然该页面的一些恶意脚本也能访问 node,可能会给用户造成损失。

Electron 中,只有在 app 模组的 ready 事件触发后才能创建 BrowserWindow。

窗口创建后就可以让窗口加载 index.html 页面了。

关闭窗口后就退出 app 应用,所以 app 退出的代码就放在窗口关闭事件中,比如:

app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});

这就是 Electron 简单应用

· 阅读需 0 分钟