创建你的第一个 Electron 项目

导读

Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作是专注于桌面应用而不是 web 服务器的,io.js 的一个变体。这不意味着 Electron 是绑定了 GUI 库的 JavaScript。相反,Electron 使用 web 页面作为它的 GUI,所以你能把它看作成一个被 JavaScript 控制的,精简版的 Chromium 浏览器。以下的教程会帮你开始创建一个简单的项目。如果你只是想创建一个基础的 Hello World 的项目来初步了解 electron,那么可以忽略带 * 标题及其以下文本的内容。

Electron 开发的环境配置

  • 安装 node

    node.js 下载链接:http://nodejs.cn/download/

    根据自己的系统选择适当的安装包。

  • 安装 electron

    打开cmd,在里面输入 npm install --g electron-prebuilt

    安装完成后运行 electron -v 检查是否安装成功,如果安装成功将会输出 electron 的版本号。

  • 安装 sublime text 3

    sublime text 3 下载连接:https://www.sublimetext.com/3

创建 Hello World 项目

Electron 应用的目录结构大体上包括:package.json,main.js,index.html。
package.json的格式和 Node 的完全一致,它的内容大概是:
			   			{
							"name"    : "your-app",
							"version" : "0.1.0",
							"main"    : "main.js"
						}
					
注意:如果 main 字段没有在 package.json 声明,Electron会优先加载 index.js。main.js 应该用于创建窗口和处理系统时间。例如:
			   			const electron = require('electron');
						const app = electron.app;//控制应用生命周期的模块
						const BrowserWindow = electron.BrowserWindow;//创建原生浏览器窗口的模块

						//保持一个对于 Window 对象的全局引用,不然,当 JavaScript 被 GC 时 Window 会被自动关闭
						var mainWindow = null;

						// 当所有窗口被关闭了,退出
						app.on('window-all-close',function() {
							//在 OS X 上,通常用户在明确地按下 cmd + Q 之前,应用会保持活动状态
							if(process.platform != 'darwin') {
								app.quit();
							}
						});

						//当 Electron 完成了初始化并且准备创建浏览器窗口的时候,这个方法就被调用
						app.on('ready',function() {
							//创建浏览器窗口
							mainWindow = new BrowserWindow({width:800,height:600});
							//加载应用的 index.html
							mainWindow.loadURL('file://E:/app/index.html');
							//打开开发者工具
							//mainWindow.openDevTools();
							//当 window 被关闭,这个事件会被发出
							mainWindow.on('close',function() {
								//取消引用 window 对象,如果你的应用支持多窗口的话,通常会把多个 window 对象存放在一个数组里面
								mainWindow = null;
							});
						});
					
最后是想要展示的 index.html:

运行你的应用

当你创建了最初的 main.js, index.html 和 package.json 这几个文件,就可以尝试在本地运行并测试。

如果你已经用 npm 全局安装了 electron-prebuilt,只需要按照如下方式直接运行你的应用:输入 dos指令 进入你的项目所在目录,然后在输入 electron .开始运行。

结果如下:

main process 和 web page 通信 *

ipcMain 模块是类 EventEmitter 的实例,当在主进程中使用它的时候,它控制着由渲染进程(web page)发送过来的异步或同步消息,从渲染进程发送过来的消息将触发事件。发送消息,事件名为 channel。回应同步消息, 可以设置 event.returnValue。回应异步消息, 可以使用 event.sender.send(...)

Main.js 里添加代码
			   			const ipcMain = require('electron').ipcMain;
						ipcMain.on('asynchronous-message', function(event, arg) {
						  console.log(arg);  // prints "ping"
						  event.sender.send('asynchronous-reply', 'pong');
						});

						ipcMain.on('synchronous-message', function(event, arg) {
						  console.log(arg);  // prints "ping"
						  event.returnValue = 'pong';
						});
					
web page 里添加代码
			   			const ipcRenderer = require('electron').ipcRenderer;
						//监听mian process里发出的message
						ipcRenderer.on('asynchronous-reply', function(event, arg) {
						  alert(arg); // 在electron中web page里的console方法不起作用,因此使用alert作为测试方法=>prints "pong"
						});
						ipcRenderer.send('asynchronous-message', 'ping');//在web page里向main process发出message
					
具体呈现在项目中的代码,main.js 同上面的介绍,而在web page 里的代码:

成功后的界面:

项目打包(两种方法)

1、源码显示(两种方法)
1.1 直接用命令打包
             				electron-packager <location of project> <name of project> <platform> <architecture> <electron version> <optional options>
             			
命令说明:

location of project:项目所在路径。

name of project:打包的项目名字。

platform:确定了你要构建哪个平台的应用(Windows、Mac 还是 Linux)。

architecture:决定了使用 x86 还是 x64 还是两个架构都用。

electron version:electron 的版本。

optional options:可选选项。

1.2-0 首先在项目根目录下面的 package.json的scripts 下添加如下代码(version,icon路径要改成自己的):
             				"packager": "electron-packager ./ HelloWorld --all --out ./outApp --version 1.4.0 --overwrite --icon=./app/img/icon/icon.ico"
             				//--all 可以换成 --platform=win32 --arch=ia32,其中 platform 是发布平台,arch=ia32 指32位windows 64位的则为x64。
             			
1.2-1 然后使用命令 npm run-script packager。最终会在你指定的目录下生成打包后的文件:

运行对应包下的.exe文件,就可以启用我们的应用了。
注意:使用以上方法我们的代码就是暴露在用户电脑上的,这非常的不安全。

2、打包成二进制文件(.asar)
2-0 使用命令 npm install -g asar 安装 asar。
2-1 使用命令 asar pack ./app app.asar 用 asar pack 打包。

执行完毕以后,在 ./ 下可以看到 app.asar 文件,将其复制到 ./OutApp/mclans.../resources/ 下,然后把 resources 下的 app 文件夹删除,运行 resources 上层的 appName.exe 文件可以启动应用了。

最后生成的 exe 文件通常较大,可以用 UPX 工具压缩,便于分发。

注意事项

1、jQuery/RequireJS/Meteor/AngularJS 的问题

jQuery 等新版本的框架,在 Electron 中使用普通的引入的办法会引发异常,原因是 Electron 默认启用了 Node.js 的 require 模块,而这些框架为了支持 commondJS 标准,当 Window 中存在 require 时,会启用模块引入的方式。分别有以下几种解决方案:

1-0、去掉框架中的模块引入判断代码。例如:
         				//比如 jQuery 中的第一行代码中
         				!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}
         				//改成:
         				!function(a,b){b(a)}
         			
1-1、使用 Electron 官方论坛提供的方法,改变require的写法。下面的代码各个框架通用:
         				//在引入框架之前先输入下面的代码
         				<script>
						window.nodeRequire = require;
						delete window.require;
						delete window.exports;
						delete window.module;
						</script>
         			
1-2、禁用Node.js的require模块化引入(如果你不想使用 Node.js 模块):
         				// In the main process.
						let win = new BrowserWindow({
						  webPreferences: {
						    nodeIntegration: false
						  }
						});
         			
1-3、为使 web 项目正常浏览,在引入 jquery 后进行判断:
         				//置于引入 jQuery 之后
         				<script>if (typeof module === 'object') {window.jQuery = window.$ = module.exports;};</script>
         			
2、关于页面跳转 的问题

刚开始看到页面跳转,大家一般会想到用 window.location.href = './index.html'; 这样的代码。结果是可以跳转,但 DOM事件 基本都会失效。到最后还是使用的 electron 提供的 ipc 接口来创建新的窗口。

2-0、在接收到命令后创建下一个窗口(创建窗口需要时间,期间可能出现空白):
         				//在main.js中::
						const ipc = require('electron').ipcMain;
						//进行监控,如果有new-window 发送过来,则重新创建一个窗口,文件是list.html
						   ipc.on('new-window',function() {
						            mainWindow.loadURL(url.format({
						            pathname: path.join(__dirname, '/views/list.html'),
						            protocol: 'file:',
						            slashes: true
						        }))
						   })