13518219792

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

如何利用Electron开发一个桌面APP

你是否曾经想过可以用 HTML、CSS 和 JavaScript 这些前端技术来构建跨平台的桌面应用?

使用 Electron 就能做到。

本文带着你深入 Electron 的核心概念。

阅读本文后,你会知道如何使用 Electron、HTML 和 CSS 构建跨平台桌面应用。

在开始之前,你可以提前看看我们在本教程中要构建的应用。

Hear Me Type [译者注:本文的示例应用名为 Hear Me Type] 功能简单直接,应用中每个键都会播放特有的声音。比如我按下了 “A”,应用会播放字母 A 特有的声音。

该应用目前有两个版本可供下载:本教程的源码,以及一个推荐给更有经验的 Electron 用户的高级版本。

因为我还在为改善应用以及添加一些新功能,所以代码会发生变化,请一定注意看看有哪些更新。

就此打住,我们现在开始学习 Electron 并用它来创建***个应用!

什么是 Electron?

Electron 是一个基于 Chrominum 和 Node.js 的跨平台桌面应用框架。

在这个框架中很容易构建基于 HTML、CSS 和 JavaScript 技术的跨平台应用。构建出来的应用会很好地兼容 Mac、Windows 和 Linux 操作系统。

它还有其它一些特性:

如果你对 Electron 的功能感到满意,我们就继续深入,创建一个简单的 Electron 应用。

动手之前需要先安装 Node.js。你还应该申请一个 GitHub 账户来保存和更新应用。虽然这个账户并不是必须的,但我非常建议你去申请一个。Github 是一个行业标准,学会使用 Github 非常重要。

我会在教程中使用 Github。

开始

准备好之后,打开系统终端窗口。

按照下面的介绍将 Electron Quick Start 这个 Git 库克隆到计算机上。

我们会基于 Electron Quick Start 来创建自己的软件。

 
 
 
 
  1. # Clone the Quick Start repository
  2. git clone 
  3. # Go into the repository
  4. cd electron-quick-start
  5. # Install the dependencies and run
  6. npm install && npm start

完成上面的步骤之后,你会看到一个像浏览器窗口的应用打开。它确实是一个浏览器窗口!

这个窗口显示的样子在不同的操作系统上会有所不同。我选择使用 Windows 的经典样式。非常赞!

Quick-Start Electron 应用的主窗口

正如我之前所说,你可以在应用中使用 Chrome 开发者工具,这个工具的用法跟在浏览器中的开发者工具一样,再赞一个!

Electron 应用程序架构

我们来看看这个应用的源代码及其文件结构。可以使用你自己喜欢的编辑器或者 IDE 打开项目,我使用 Atom …… 你猜到了 …… 它就是用 Electron 构建的![译者注:我比较喜欢 VSCode,也是基于 Electron 构建的]

新应用的目录和文件结构。

我们有一个基本的文件结构:

electron-quick-start

文件结构类似于我们创建网页的结构。

我们有:

也许你对主进程和渲染进程存有疑问。它们到底是什么,用来干什么?

很高兴你有此疑问。注意了,如果你来自浏览器的 JavaScript 领域,这对你来说可能是一块新的领域!

什么是进程?

看到“进程”这个词的时候,想像一下操作系统级的进程。那是运行在系统中的计算机程序实例。

启动 Electron 应用之后,查看 Windows 的任务管理器或者 macOS 的活动监视器,就可以看到与这个应用相关的进程。

这些进程都是并行运行的,为每个进程分配的内存和资源相互隔离。

如果我想创建一个 for 循环在渲染进程中逐步处理一些事件。

 
 
 
 
  1. var a = 1;
  2. for ( a = 1; a < 10; a ++) {
  3.  console.log('This is a for loop');
  4. }

这些改变只在渲染进程中有效,根本不会对主进行造成影响。“This is a for loop”消息只会出现在渲染模块中。

主进程

主进程控制着应用的生命周期。它内置了完整的 Node.js API,可以打开对话框,创建渲染进程,还可以处理其它其它与操作系统的交互操作,包括启动和退出应用。

按照惯例,这个进程写在名为 main.js 的文件中。不过你想使用其它名字也没有问题。

你可以在 package.json 文件中配置主进程文件的名称。

试验一下,打开 package.json 并将

 
 
 
 
  1. “main”: “main.js”,

修改为

 
 
 
 
  1. “main”: “mainTest.js”,

启动应用看看它是否仍然正常运行。

注意,主进程只有一个。

渲染进程

应用中的渲染进程是一个浏览器窗口。与主进程不同,可以存在多个独立的渲染进程。

因为渲染进程是各自独立的,如果其中一个崩溃了并不会影响到其它进程,这得益于 Chrominum 的多进程架构。

这些浏览器窗口就像演示网页一样,也可以被隐藏或自定义。

不过 Electron 内置了完整的 Node.js API,也就是说我们可以打开对话框或进行其它与操作系统的交互。

这样考虑;

[来源: Kristian Poslek]

还有一个问题,它们能以某种方式联系起来吗?

这些进程都在独立运行,但他们仍然需要通信,因为它们负责不同的任务,这尤其需要通信。

为此,存在一个进程间的通信系统或者 IPC。你可以使用 IPC 在主进程和渲染进程间进行通信。对于这个知识点更深入一些的解释,请阅读 Christian Engvall 的文章。

上面说的都是开发 Electron 应用的基础知识。

现在回到我们的代码!

私有化

让我们给应用所在的目录起一个合适的名称。

将目录名从 electron-quick-start 改为 hear-me-type-tutorial。

重新在编辑器或 IDE 中打开这个目录,我们打开 package.json 来进一步定制应用标识。

package.json 包含了至关重要的应用信息。这里定义应用的名称、版本、主文件、作者、许可协议等。

现在把作者改成自己的名称,自豪感油然而生。

找到 “author” 参数,然后将值改成自己的名称。它看起来像这样:

 
 
 
 
  1. “author”: “Carol Pelu”,

我们还要改其它一些参数。在 package.json 中找到 name(名称) 和 description(说明)并修改它们:

帅呆了!现在应用有了新名称,还有简短而清晰的说明。

记住,你可以在终端运行 npm start 来运行应用,以观察所做的改变。

我们会继续在应用中添加一些期望的功能。我们想在按下每个键的时候播放不同的声音。

哦,有趣的功能!

没有功能的应用是什么?什么都不是……

现在我们要给它添加功能。

为了让应用响应输入,我们必须定义一个元素来捕捉事件,然后触发期望的动作。

为此,我们会创建一个具有特殊名称的若干 audio 元素,对应于按键。然后我们会使用一个 switch 语句来定位按下的键,播放与之关联的声音。

如果你现在觉得有点复杂,不要怕,我会指引你一步步进行。

下载这个压缩包,它包含了我们要使用的所有声音文件。很快就会用到!

我们会打开 index.html 文件,创建一个

在 元素内部,创建一个 div 元素,将其 class 属性设置为 audio。

在刚刚创建的 div 元素,创建

preload=”auto” 用于告诉应用在页面加载的时候就加载完整的声音文件。index.html 是应用的主文件,所有声音都会在应用启动的时候加载。

下面是代码:

 
 
 
 

你的 index.html 应该就像这样。

现在 指向一个未知的文件。我们要创建一个名为 soudes 的目录,并将所有声音文件解压到这个目录中。

非常好!现在唯一缺少的是 JavaScriopt 代码。

创建一个叫 functions.js 的新文件,并在 index.html 中通过 require 引用它,这样应用运行的时候才会执行 JS 代码。

在示例的 require(./renderer.js') 下载添加这样一行:

 
 
 
 
  1. require('./functions.js')

之后项目看起来是这样的:

不错!一切就绪,下面是见证奇迹的时刻。

打开 functions.js 文件并将下面的代码添加到文件中。我稍后解释这段代码。

 
 
 
 
  1. document.onkeydown = function(e) {
  2.     switch (e.keyCode) {
  3.         case 65:
  4.             document.getElementById('A').play();
  5.             break;
  6.         default:
  7.             console.log("Key is not found!");
  8.     }
  9. };

代码现在是这样:

打开 Bash 或者终端窗口,确保当前是在项目目录下,运行 npm start 来启动应用。

调整扬声器的音量并敲下按键。

 
 
 
 
  1. #MindBlown

JS 代码非常简单明了。

我们使用了 document 对象上的 onkeydown 事件,在这里找到被访问的元素。记住,document 对象是应用的主窗口。

我们在在匿名函数中使用了 switch 语句,根据 Unicode 值来判断按键。

如果找到按键对应的 Unicode 值,就会播放相应的声音,否则抛出 “not found” 错误。这个错误要在控制台中去找。

多么愉快的过程!

你可能注意到了,我们的声音文件包含了 A-Z 和 0-9 这些键,把它们都用起来。

在 index.html 中为每个有对应声音文件的键都创建一个 元素。

之后代码就像这样:

当然你可以用拷贝粘贴:

 
 
 
 

现在在 functions.js 中加点代码。

你可以在这个网站上查到字符码(charCode 或 keyCode)。

当然,也可以使用拷贝粘贴:

 
 
 
 
  1. document.onkeydown = function(e) {
  2.     switch (e.keyCode) {
  3.         case 48:
  4.             document.getElementById('0').play();
  5.             break;
  6.         case 49:
  7.             document.getElementById('1').play();
  8.             break;
  9.         case 50:
  10.             document.getElementById('2').play();
  11.             break;
  12.         case 51:
  13.             document.getElementById('3').play();
  14.             break;
  15.         case 52:
  16.             document.getElementById('4').play();
  17.             break;
  18.         case 53:
  19.             document.getElementById('5').play();
  20.             break;
  21.         case 54:
  22.             document.getElementById('6').play();
  23.             break;
  24.         case 55:
  25.             document.getElementById('7').play();
  26.             break;
  27.         case 56:
  28.             document.getElementById('8').play();
  29.             break;
  30.         case 57:
  31.             document.getElementById('9').play();
  32.             break;
  33.         case 65:
  34.             document.getElementById('A').play();
  35.             break;
  36.         case 66:
  37.             document.getElementById('B').play();
  38.             break;
  39.         case 67:
  40.             document.getElementById('C').play();
  41.             break;
  42.         case 68:
  43.             document.getElementById('D').play();
  44.             break;
  45.         case 69:
  46.             document.getElementById('E').play();
  47.             break;
  48.         case 70:
  49.             document.getElementById('F').play();
  50.             break;
  51.         case 71:
  52.             document.getElementById('G').play();
  53.             break;
  54.         case 72:
  55.             document.getElementById('H').play();
  56.             break;
  57.         case 73:
  58.             document.getElementById('I').play();
  59.             break;
  60.         case 74:
  61.             document.getElementById('J').play();
  62.             break;
  63.         case 75:
  64.             document.getElementById('K').play();
  65.             break;
  66.         case 76:
  67.             document.getElementById('L').play();
  68.             break;
  69.         case 77:
  70.             document.getElementById('M').play();
  71.             break;
  72.         case 78:
  73.             document.getElementById('N').play();
  74.             break;
  75.         case 79:
  76.             document.getElementById('O').play();
  77.             break;
  78.         case 80:
  79.             document.getElementById('P').play();
  80.             break;
  81.         case 81:
  82.             document.getElementById('Q').play();
  83.             break;
  84.         case 82:
  85.             document.getElementById('R').play();
  86.             break;
  87.         case 83:
  88.             document.getElementById('S').play();
  89.             break;
  90.         case 84:
  91.             document.getElementById('T').play();
  92.             break;
  93.         case 85:
  94.             document.getElementById('U').play();
  95.             break;
  96.         case 86:
  97.             document.getElementById('V').play();
  98.             break;
  99.         case 87:
  100.             document.getElementById('W').play();
  101.             break;
  102.         case 88:
  103.             document.getElementById('X').play();
  104.             break;
  105.         case 89:
  106.             document.getElementById('Y').play();
  107.             break;
  108.         case 90:
  109.             document.getElementById('Z').play();
  110.             break;
  111.         default:
  112.             console.log("Key is not found!");    
  113.     }
  114. };

大功告成!

应用的主要功能已经完成了,但仍然还有些工作要做!

完善!

应用程序的功能已经完成,但它尚不完善。

比如,可以在 index.html 中修应用的标题和主窗口的内容。

此外,这个应用没有设计炫丽的色彩,也没有使用漂亮的图片。

充分发挥你的想像,找出改进应用设计的方法。

代码也不***,我们有很多相同的代码需要优化以减少代码行数,至少看起来不那么难受。

重复代码真不是好做法!

测试!就是测试!

好的软件需要通过测试。

我建议你先按键看看,会发生什么事。

***的情况是你会听到每个键对应的声音。但如果你快速的按下多个键的时候会发生什么呢?如果按下了非预期的键,比如 Home 和 NumLock,又会发生什么呢?

如果你最小化程序再尝试着按钮会怎样?能听到声音吗?如果没有选择应用程序窗口,按下键盘时,还会听到声音吗?

答案是否定的。

Electron 的架构决定了其行为。它允许你可以像 C# 语言那样使用所有按键,但你不能注册个性化的按键。这已经超出了 Electron 应用的使用范围。

一行行的执行代码,并深度中断它,看看会发生什么,Electron 会抛出什么样的错误。这一练习能帮助你更好地进行调试。如果你知道应用的缺陷,那么你就知道该如何去修复,让应用变得更好。

我故意在 functions.js 文件中使用了一个废弃的 JavaScript 事件,你能发现吗?

如果你找到了,我希望你能在不改变应用程序功能的情况下替换它。

使用废弃的代码很不好,这可能会导致严重错误,你甚至可能意识不到这些错误的存在。关注语言的***文件,了解可能发生的变化,始终了解***状态。


网页名称:如何利用Electron开发一个桌面APP
文章来源:http://cdbrznjsb.com/article/dpgodjh.html

其他资讯

让你的专属顾问为你服务