使用Electron创建跨平台桌面应用

2019-03-27 15:08:01 浏览数 (1)

开发和维护一个桌面应用是比较复杂的,所以可以理解现在的公司门为何推动WEB应用或者各种跨平台版本,在过去的十几年里,已经有了很多尝试,Flash、Air、Java和Sliverlight,他们都各自取得了不同程度的成功

但是最主要的问题就是他们通常需要开发者学习另一种语言,或者强制用户安装插件带来的稳定性、性能和安全问题。

我们都知道现在出现了一些使用JavaScript和web技术来开发跨平台的桌面应用的方案。

Electron, GitHub提供的一种方案,我已经尝试的构建了几个应用。经过两年的开发,包括一次名字更改 (Atom shell), Electron发布了1.0版本,这已经是一个合适的机会来看看Electron有怎样的能力。

安装 Electron

Electron有 quick start project 和 pre-built releases 可用, 我们也可以使用 npm来安装

代码语言:javascript复制
`npm install electron-prebuilt -g`

Mac用户可以使用 HomeBrew 安装, via Cask:

代码语言:javascript复制
`brew install Caskroom/cask/electron`

不管你使用哪种方式安装,你都会得到一个可执行的Electron二进制文件。

这个文件是用于打包并且运行你的Electron项目,你可以使用任何文本编辑器或者IDE来编写你的项目代码。

一个Electron项目包含三个文件:

  • index.html: 初始页面。
  • main.js: 用于启动应用并渲染页面。
  • package.json: 项目依赖信息。

例子:your need a hero

在这个例子里面我将会创建一个简单的应用,它会使用 Marvel API 拉取25位超级英雄的信息并且显示他们的名字和缩略图,创建完成之后的应用会有一个应用图标,最终使用的用户不会知道到应用是如何被创建的也不能看到程序的源代码。

你可以在 GitHub 找到这个项目的源代码。

打开 package.json 增加如下项目依赖:

代码语言:javascript复制
{
  "name": "hero-browser",
  "version": "0.1.0",
  "main": "main.js",
  "dependencies": {
    "dotenv": "^2.0.0",
    "md5": "^2.1.0"
  }
}

这是一个和node.js项目有着相同格式的 package.json文件,在这里描述了应用名称、版本号、入口文件以及项目依赖。

增加完成之后运行 npm install安装项目依赖。

main.js 可以使用JavaScript代码操作计算机,本项目只是一个简单的例子,你可以在这里找到Electron更多的功能Electron’s documentation。

首先,我们先完成Electron项目必须项:创建app、浏览器窗口以及主窗口变量。

代码语言:javascript复制
'use strict';

const electron = require('electron');
const app = electron.app;  // Module to control application life.
const BrowserWindow = electron.BrowserWindow;  // Module to create native browser window.
var mainWindow = null;

现在让我们处理当视窗关闭时应用程序退出,如果是OS X操作系统,当所有视窗关闭时 应用程序依旧处于打开状态,但是用户通常是为了退出应用程序,所以我们必须用如下方式处理这种场景。

代码语言:javascript复制
app.on('window-all-closed', function() {
    if (process.platform != 'darwin') { 
        app.quit();
    }
});

一旦Electron初始化就会创建一个浏览器窗口并且加载应用程序代码,当浏览器窗口关闭时 销毁窗口对象。

代码语言:javascript复制
app.on('ready', function() {
  mainWindow = new BrowserWindow({width: 800, height: 600});
  mainWindow.loadURL('file://'   __dirname   '/app/index.html');

  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

创建一个叫做 app的子文件夹,并且在 app/index.html文件中添加stylesheets样式表以及JavaScript文件并且构建界面HTML。

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Marvel Super Hero Browser</title>
    <link href="css/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <h1>Marvel Super Hero Browser</h1>
    <em>Thanks to Marvel for their API.</em>

    <div id="character_list"></div>

    `<script src="js/index.js">`</script>
</body>
</html>

创建 app/css/index.css 并添加一些基本的样式布局。

代码语言:javascript复制
#character_list .character img {
    width: 100px;
}

.character {
    float: left;
    padding: 25px;
    max-width: 100px;
}

创建 app/js/index.js,这里会有程序的主要功能。首先定义依赖和所需要的变量:

代码语言:javascript复制
'use strict';

require('dotenv').config();
var md5 = require('md5');
var publicKey = process.env.MARVEL_PUBLIC_KEY;
var privateKey = process.env.MARVEL_PRIVATE_KEY;
var ts = String(new Date().getTime());
var hash = md5(ts privateKey publicKey);

var url = `https://gateway.marvel.com/v1/public/characters?ts=${ts}&apikey=${publicKey}&hash=${hash}&limit=25`;

使用Marvel API需要权限验证, 登录Marvel 然后 跟随这份指南获取所需要的三个参数,使用dotenv package库来管理配置文件, 验证所需要的的 privatekeypublickey存储在 .env文件中。

代码语言:javascript复制
MARVEL_PRIVATE_KEY=<PRIVATE_KEY>
MARVEL_PUBLIC_KEY=<PUBLIC_KEY>

limit参数用于设置一次请求多少条数据,还有其他可用的参数可以设定。

如果你不想使用Marvel API,我也为你提供了一个JSON数据,使用以下代码替换Marvel API地址:

代码语言:javascript复制
'use strict';

var url = `https://gist.githubusercontent.com/ChrisChinchilla/29486e8ce367f426dfe6b15dbcc3fa54/raw/3ea92af51ce3749bb5983c1cb0359883592daef6/Marvel%20Electron%20Data`;

接下来创建创建生成插入 character_listdiv的每一个角色的HTML字符串方法:

代码语言:javascript复制
var characterHTML = (character)=> `
  <div class="character">
    <h2>${character.name}</h2>
    <img src="${character.thumbnail.path}.${character.thumbnail.extension}" />
  </div>`;

然后调用API,得到的JSON格式的角色信息在 resp.data.results

为每一个角色生成HTML元素并且插入到 character_list,通过Marvel API得到的角色图片被分为文件名(file name)和扩展名(extension),如果没有可用的角色图片,则会返回一张显示为 ‘no image available’的图片,我们可以很轻易的处理这种情况,但不会在这个例子中做处理。

当整个过程完成之后,调用系统API显示一个通知,并捕获可能出现的异常情况:

代码语言:javascript复制
fetch(url)
    .then(resp => resp.json())
    .then(json => json.data.results)
    .then(characters => {
        var html = characters.map(characterHTML).join('');
        var characterList = document.getElementById("character_list");
        characterList.innerHTML = html;

        new Notification(document.title, {
            body: 'Super Heroes Loaded!'
        });
    })
    .catch((error)=> {
        console.error(error);
    });

在命令行通过在项目根目录执行以下命令运行项目:

代码语言:javascript复制
`electron .`

打包应用程序

打包代码成为一个 原生应用非常简单只需要一个应用图标,它的外观和文件类型取决于你的应用运行的操作系统,我在这里使用的图标来自Marvel官方的安卓APP。

注意: 这里我们使用受版权保护的图标用于教学目的,请不要使用他们用于自己的项目。

然后我使用了iconverticons.com/online/ 把PNG格式图片转换为MAC所需要的应用程序图标,当然还有其他可用的转换工具。

最简单的打包方法是使用 electron-packager,这是一个npm模块(注意:需要单独安装),他可以生成一个体积比较大的二进制文件,当然对于桌面应用来讲这应该不算是什么大问题,如果你比较在意体积大小,这里有另外一个选择。

如果你在一个非Windows的操作系统上打包Windows应用,那么你需要安装Wine。

在命令行使用如下命令打包你的应用(替换为你的项目相关的参数):

代码语言:javascript复制
`electron-packager /Users/chrisward/Workspace/sp_electron MarvelBrowse --platform=darwin --arch=x64 --version=0.36.10 --out=/Users/chrisward/Workspace --overwrite --icon=/Users/chrisward/Workspace/sp_electron/marvel-app.icns`

这些参数将要被设置:

  • 项目路径。
  • 生成的应用名称。
  • 所运行的操作系统: win32 用于 Windows, linux, darwin 用于 vanilla Mac OS X , mas 用于 Mac App store 发布应用. 设置为 all会生成所有操作系统的二进制文件。
  • The architecture: ia32x64 分别用于 32位操作系统和64位操作系统,当然也可以设置为 all
  • Electron的版本。
  • 生成二进制文件的路径。
  • 所使用的应用程序图标。

主意: 参数可以为多个并使用逗号分开值,如果你想生成所有平台的二进制文件可以替换相关参数为 --all

还在对Electron保持怀疑?我写这篇文章使用 Atom,我与编辑联系使用Slack ,我用来测试程序使用的Docker容器通过 Kitematic创建,他们都是使用Electron生成的应用程序。


往期精选文章

使用虚拟dom和JavaScript构建完全响应式的UI框架

扩展 Vue 组件

使用Three.js制作酷炫无比的无穷隧道特效

一个治愈JavaScript疲劳的学习计划

全栈工程师技能大全

WEB前端性能优化常见方法

一小时内搭建一个全栈Web应用框架

干货:CSS 专业技巧

四步实现React页面过渡动画效果

让你分分钟理解 JavaScript 闭包



小手一抖,资料全有。长按二维码关注京程一灯,阅读更多技术文章和业界动态。

0 人点赞