深入浅出Electron

 1、electron基本介绍

Electron(官网:https://www.electronjs.org/zh/)是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源框架。 

Electron提供了丰富的本地(操作系统)API,使你能够使用纯JavaScript来创建桌面应用程序。Electron通过集成浏览器内核,使用Web技术来实现不同平台下的渲染,并结合了 Chromium 、Node.js 和用于调用系统本地功能的 API 三大板块。

  1. Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用;
  2. Chromium 为 Electron 提供强大的 UI 渲染能力,由于 Chromium 本身跨平台,因此无需考虑代码的兼容性。
  3. Chromium 并不具备原生 GUI(图形用户界面(Graphical User Interface)) 的操作能力,因此 Electron 内部集成 Node.js,编写 UI 的同时也能够调用操作系统的底层 API,例如 path、fs、crypto 等模块。
  4. Native API 为 Electron 提供原生系统的 GUI 支持,借此 Electron 可以调用原生应用程序接口。

总结起来,Chromium 负责页面 UI 渲染,Node.js 负责业务逻辑,Native API 则提供原生能力和跨平台。

 

1.1、发展历史

  • 2013年4月 Atom Shell 项目启动 。(Electron于2013年作为构建 Github上可编程的文本编辑器Atom的框架而被开发出来。)
  • 2014年5月 Atom Shell 被开源 。
  • 2015年4月 Atom Shell 被重命名为 Electron 。
  • 2016年5月 Electron 发布了 v1.0.0 版本 。
  • 2016年5月 Electron 构建的应用程序可上架 Mac App Store 。
  • 2016年8月 Windows Store 支持 Electron 构建的应用程序 。

 

1.2、electron优缺点

优点:

  1. 原生的接口(菜单、消息提醒、系统托盘等)
  2. 上手难度低。能够使用react、vue等前端框架,能方便地迁移前端组件,构建出漂亮的桌面应用
  3. 方便热更新
  4. 调试和测试方便
  5. Electron 开发文档齐全

 

缺点:

  1. 因为Electron捆绑了浏览器chromium内核和Node.js,所以它更倾向于创建大型应用,一个简单的Electron应用程序在没有压缩的情况下通常体积约120MB,不太适合开发轻量级的应用
  2. 相比c++开发的桌面应用,性能不如后者
  3. 每个窗口都是一个新的进程,占据大量内存
  4. 启动速度较慢
  5. Electron允许用户通过开发者工具和ASAR源文件轻松访问源代码,不太安全
  6. 不支持手机端

 

1.3、electron和Qt的对比

跨平台应用开发框架 electron 和 QT的对比:

electron QT
开发简单,上手快速 上手慢,但是性能高
适用于一些单一功能的应用开发,一旦项目过大,可能会有性能问题,适合想要把网页版和桌面端共享代码 较为底层,与系统相关联,全平台兼容性好。适合复杂系统
electron开发的一些应用样例一些大型electron项目,像是atom跟vscode也是主要集中文本处理方面,没有过多的其他功能 适用于复杂较为大型的项目开发,像是yy语音,wps,vituralbox。与硬件相关的复杂系统像是地理信息系统,军工系统
使用JS开发 使用C++,绘制界面可以使用QML,标记语言类js
安全性能一般,开发流程短 安全性能高,但开发流程长

 

  • Qt适合一些性能要求高的桌面应用。
  • Electron适合一些偏业务的应用,对性能没有很多要求,主要是业务逻辑和UI展示,比较轻量级的应用。因为Electron可以一份代码同时得到网页版和桌面版,所以如果你的应用还需要网页版,那么Electron可以极大地节省你的开发和维护成本。
 

1.4、使用electron开发的实际案例

 

2、安全相关

无法保护 Electron 源代码,是很多开发者提及最多的问题之一。Electron 使用 javascript 来构建桌面应用程序,这使得黑客很容易对 electron 应用程序进行进行解包、修改逻辑破解商业化限制、重新打包,再重新分发破解版。

要想真正解决问题,除了把所有商业化逻辑做到服务端,我们还需要对代码进行签名、进行安全加固,避免解包、篡改、二次打包、二次分发。

 

2.1、代码签名

代码签名概念:代码签名是一种用来证明应用是由你创建的一种安全技术,代码签名用于使用来自受信任的证书颁发机构(如Gworg)的数字签名对程序文件、可执行文件、软件包、脚本和软件更新进行签名。操作系统能通过代码签名检测对app的任何修改,包括意外修改和来自恶意代码的修改,可以在安装和执行期间对签名文件进行身份验证。可以理解为蜡封,它向收件人保证该软件来自受信任的作者并且没有被篡改。实际上开发者可以发布一个未签名的应用程序,但是我们并不建议这样做。用户在打开未签名的应用时,操作系统会弹出对话框提示:直接删除应用或者取消运行。

如果你正在开发一款Electron应用,并打算将其打包发布,那你就应该为其添加代码签名。在获得代码签名证书之后,通过 electron forge、electron-builder 等打包工具,只需几行配置即可方便地给打包的 electron 应用进行签名。

 

2.2、安全加固

目前很多 Electron 程序的是没有做加密保护的,很多都只是将文件打包成 asar,但是 asar 通过命令行即可解压出源文件,并不存在什么加密的过程。可以使用第三方服务提供的(如 Virbox Protector 等(企业手机银行使用的是梆梆安全))安全加固技术通过控制流混淆、字符串转换加密、变量名混淆、隐藏函数调用等多种加密方法保护代码安全,对 js 文件进行加密,加密后再打包成 asar,达到很高的安全性,防止代码反编译。

 

3、electron的基本使用

3.1、创建一个 electron 项目

在使用Electron进行开发之前,您需要安装 Node.js,最低工作版本为 14.x,低于 14 的版本在后面的打包过程中可能会报错。

(注意,因为 Electron 将 Node.js 嵌入到其二进制文件中,所以在 electron 应用运行时的 Node.js 版本与你本地电脑中运行的 Node.js 版本无关。)

(虽然您需要在开发环境安装 Node.js 才能编写 Electron 项目,但是 Electron 不使用您系统的 Node.js 环境来运行它的代码。 相反地,它使用 electron 内置的 Node.js 运行时。 这意味着您的终端用户不需要 Node.js 环境也可以运行您的应用。要查看您应用内置的 Node.js 版本,您可以访问主进程 (main process) 或预加载脚本 (preload script) 中的 process.versions 变量。 您也可以参考 electron/releases 仓库中的版本列表。)

 

Electron 应用程序遵循与其他 Node.js 项目相同的结构,首先创建一个初始 npm 项目:

mkdir my-electron-app && cd my-electron-app
npm init

设置entry point为 main.js,author 与 description 可为任意值,但对于应用打包是必填项。

在跑完案例所有步骤后最终完整的 package.json 文件应该类似如下:

{
    "name": "my-electron-app",
    "version": "1.0.0",
    "description": "Hello World!(my test)",
    "main": "main.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "electron-forge start",
        "package": "electron-forge package",
        "make": "electron-forge make"
    },
    "author": "wenxuehai",
    "license": "ISC",
    "devDependencies": {
        "@electron-forge/cli": "^6.0.5",
        "@electron-forge/maker-deb": "^6.0.5",
        "@electron-forge/maker-rpm": "^6.0.5",
        "@electron-forge/maker-squirrel": "^6.0.5",
        "@electron-forge/maker-zip": "^6.0.5",
        "electron": "^23.0.0"
    },
    "dependencies": {
        "electron-squirrel-startup": "^1.0.0"
    }
}

然后,将 electron 包安装到应用的开发依赖中。

npm install --save-dev electron

在 package.json配置文件中的scripts字段下增加一条start命令:

{
  "scripts": {
    "start": "electron ."
  }
}

在项目根目录下创建一个空白的 main.js 文件。任何 Electron 应用程序的入口都是 main 文件。 这个文件控制了主进程,它运行在一个完整的Node.js环境中,负责控制您应用的生命周期,显示原生界面,执行特殊操作并管理渲染器进程。

执行 npm start命令运行 electron 应用,Electron 将依据应用中 package.json配置下main字段中找到对应的入口文件。

 

3.2、创建应用窗口和页面

在为我们的应用创建窗口前,我们先创建加载进该窗口的内容。 在Electron中,各个窗口显示的内容可以是本地HTML文件,也可以是一个远程url。

demo 示例:创建一个 index.html 文件作为窗口页面,main.js 文件作为入口文件,预加载脚本来编辑页面内容。

文件内容分别如下,详细解释可参考官网:https://www.electronjs.org/zh/docs/latest/tutorial/quick-start#运行主进程

<!--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'">
    <title>你好!</title>
</head>

<body>
    <h1>你好!</h1>
    我们正在使用 Node.js <span id="node-version"></span>,
    Chromium <span id="chrome-version"></span>,
    和 Electron <span id="electron-version"></span>.

    <!-- 您也可以此进程中运行其他文件 -->
    <script src="./renderer.js"></script>
</body>

</html>

main.js 内容:

// main.js

// electron 模块可以用来控制应用的生命周期和创建原生浏览窗口
const { app, BrowserWindow } = require("electron");
const path = require("path");

const createWindow = () => {
    // 创建浏览窗口
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__dirname, "preload.js"),
        },
    });

    // 加载 index.html
    mainWindow.loadFile("index.html");

    // 打开开发工具
    // mainWindow.webContents.openDevTools()
};

// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
    createWindow();

    app.on("activate", () => {
        // 在 macOS 系统内, 如果没有已开启的应用窗口
        // 点击托盘图标时通常会重新创建一个新窗口
        if (BrowserWindow.getAllWindows().length === 0) createWindow();
    });
});

// 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 因此, 通常
// 对应用程序和它们的菜单栏来说应该时刻保持激活状态,
// 直到用户使用 Cmd + Q 明确退出
app.on("window-all-closed", () => {
    if (process.platform !== "darwin") app.quit();
});

// 在当前文件中你可以引入所有的主进程代码
// 也可以拆分成几个文件,然后用 require 导入。

perload.js内容:

// preload.js

// 所有的 Node.js API接口 都可以在 preload 进程中被调用.
// 它拥有与Chrome扩展一样的沙盒。
window.addEventListener("DOMContentLoaded", () => {
    const replaceText = (selector, text) => {
        const element = document.getElementById(selector);
        if (element) element.innerText = text;
    };

    for (const dependency of ["chrome", "node", "electron"]) {
        replaceText(`${dependency}-version`, process.versions[dependency]);
    }
});

最后,执行npm start,将打开一个 electron 应用,如下:

 

4、打包应用程序(window平台)

 

Electron 的核心模块中没有捆绑任何用于打包或分发文件的工具。 如果您在开发模式下完成了一个 Electron 应用,可使用electron社区所支持的打包工具来生成特定于平台的程序包,如生成 macOS 上的 Apple Disk Image (.dmg)、Windows 上的 Windows Installer (.msi) 或 Linux 上的 RPM Package Manager (.rpm)等等。

 

4.1、使用 Electron Forge 打包

Electron Forge 是一个处理 Electron 应用程序打包与分发的一体化工具。 在工具底层,它将许多现有的 Electron 工具 (例如 electron-packager、 @electron/osx-signelectron-winstaller 等) 组合到一起,因此您不必费心处理不同系统的打包工作。

将 Electron Forge 添加到您应用的开发依赖中,并使用其"import"命令设置 Forge 的脚手架,将项目导入至 Electron Forge。命令如下:

npm install --save-dev @electron-forge/cli
npx electron-forge import

执行以上命令后,Forge 会将一些脚本添加到您的 package.json 文件中。并且会生成一个配置文件 orge.config.js。

  //...
  "scripts": {
    "start": "electron-forge start",
    "package": "electron-forge package",
    "make": "electron-forge make"
  },
  //...

要创建可分发文件,请使用项目中的 make 脚本,该脚本最终运行了 electron-forge make 命令。执行命令如下:

npm run make

该 make 命令包含两步:

  1. 它将首先运行 electron-forge package ,把您的应用程序 代码与 Electron 二进制包结合起来。 完成打包的代码将会被生成到一个特定的文件夹中。
  2. 然后它将使用这个文件夹为每个 maker 配置生成一个可分发文件。

Electron-forge 会创建 out 文件夹,其中包括可分发文件与一个包含其源码的文件夹。在该文件夹下可以找到安装包 setup.exe 和运行程序 exe。

 

4.1.1、打包报错解决方法

运行以下命令可以会报错:

npx electron-forge import

报错信息如下:

这是因为 node 版本过低导致的,使用 electron 时 node 最低需要 14.x 版本。

 

5、打包应用程序(Linux平台)

本来 electron-builder是支持在windows下开发,然后一条命令打包到不同平台的,但此命令需要使用远程服务器来完成打包,然后此服务器已经停止很长时间了,而且从官方文档可感知后续不会开启。所以要打linux包必须到linux平台下打包。

Windows下无法打linux版本的包,如果你要打linux系统的amd64架构需要找一台linux amd64的系统打包,也可以在amd64下打arm架构的包,但是不能运行,需要放到arm架构的系统里才能运行。

 

5.1、electron builder打包

参考:https://blog.51cto.com/u_12303347/5424258https://www.cnblogs.com/tuyile006/p/16399745.html

照上述步骤打包可能会报错,如下:

这是因为 ico 图标不支持 Linux系统,此时应该找到代码中所有用到 favicon.ico 的地方,将其改为 xxx.png ,即改成png图片,并将该 png 图片放在跟之前 favicon.ico 相同位置上。(实际上应该只需要改electron-builder.json5文件即可。)

 

打包成功后,在 release 目录下将会生成一个 AppImage 文件,该文件就是 Linux 系统上的可执行文件。

 

先赋予该文件可执行权限,然后再直接执行即可:

// 赋予AppImage文件可执行权限:
chmod a+x AppImage文件的路径

//运行AppImage程序(下面如果是通过root用户运行,则可能需要加上 --no-sandbox参数)
./AppImage文件   

 

posted @ 2023-02-08 21:12  wenxuehai  阅读(2698)  评论(0编辑  收藏  举报
//右下角添加目录