Electron简介
发布于 4 小时前 作者 CarlosRen 39 次浏览 来自 分享

Electron

introduction

1.1 Electron是什么?

引用官网的一句话: Build cross platform desktop apps with JavaScript, HTML, and CSS

1.2 诞生

技术背景:

JavaScript近几年的全领域发展,个人理解JavaScript是思想对java的前进,从compile once,run everywhere转变为code once,run everywhere,由于JavaScript本身的是一门解释性的脚本语言,这让它逐渐的成为全宇宙使用最广泛的语言,没有之一。

JavaScript只是JavaScript,在浏览器中,它操作DOM和BOM,在服务器端它操作FileSystem,HTTP,所以在任何环境,他都可以执行,即使是在几M的内存环境,这点对物联网来说很重要。

调用需求:

传统的PC软件开发成本太高,和网络的兴起,让传统的开发逐渐被在线系统吊打,高成本必然逐渐的走下坡路,这是符合经济上发展的趋势,但是由于性能的问题,不管是VR还是直播,需要采集视频,音频,网卡信息,而这些模块大多数还是C、C++来获取

传统局限: 在浏览器里,Web页面通常运行在一个沙盒环境里,它不能访问本地的资源。 比如在Web页面里,调用本地GUI是不允许的,因为在Web页面里管理本地GUI资源是非常危险的而且非常容易导致资源泄露。如果你想在Web页面进行GUI操作,该Web页面的渲染进程必须通过和主进程通信来请求主进程处理这些操作。

1.3 Electron的组成

1.软件成分: Electron: 1.2.6 Node: 6.1.0 Chromium: 51.0.2704.106 V8: 5.1.281.65 (各方面都足够新,ES和TS都可以撸代码)

2.工具支持:(官方提供) 功能上支持: Automatic updates Native menus & notifications App crash reporting Debugging & profiling Windows installers

写代码&部署: Electron Packager — Package your apps
Electron Builder — Deploy your apps Spectron — Test your apps Devtron — Debug your apps Electron Prebuilt — Install Electron
Menubar — Create menubar apps

3.萌新的学习材料: 官网提供一个比较全面的DEMO,包括常规的系统级别操作,通信,截图,调用PDF等例子 API支持多语言,已经翻译好,个别翻译会让读者懵逼 API中有不少例子,但是不是很全,个人觉得是用的人比较少,有可能会有填坑的情况

4.成熟产品: 官网上列举了很多,个人觉得做的比较好的是:VSC和白鹭的IDE (由于白鹭的IDE主要作者是我师哥,之前跟他学习了一下,整个下午都是在卧槽!!的状态)

quick start

2.1 搭建开发环境

1.官网是有个一个quick start的例子的,我推荐先下载demo点点看看,传送门

2.下载官方的quick start的例子:

# Clone the Quick Start repository
$ git clone https://github.com/electron/electron-quick-start

# Go into the repository
$ cd electron-quick-start

# Install the dependencies and run
$ npm install && npm start

但是如果有小伙伴没翻墙,被拦在的寡妇网内,npm install失败了,那就用下面这个办法吧 (换了源也不好使的话)

根据系统去淘宝的镜像上下载最新的Electron包,传送门

我是windows,解压之后可以点击electron.exe就可以看到提示

To run your app with Electron, execute the following command in your Console (or Terminal):
C:\Users\carlos\Desktop\electron\electron.exe path-to-your-app

把工程的文件夹拖进来,或者执行cmd命令就可以看到效果了,我是觉得这里可以加到环境变量里,但是没完成功,留个小坑以后填

注意,Electron的Console.log()是输出到控制台的,所以当你concole一个东西看不到的时候,试试CMD启动

现在

  • api √
  • demo √
  • quick-start √
  • run environment√
  • Hello world √

恭喜你已经入坑了

First Electron

如果你是一个好学的同学,那你应该自己琢磨quick-start,如果你是懒癌晚期,那就继续听我逼逼

3.1 请建立以下目录

your-app
- main.js
- index.html
- package.json

3.2 说明

package.json 的格式与Node的模块格式是一致的,可以引入依赖

{
  "name": "electron-quick-start",
  "version": "1.0.0",
  "description": "A minimal Electron application",
  "main": "main.js"
}

这里要注意的是,现在的Electron已经不指定main.js做为入口了,在package.json中可以设置启动入口

main 就是你应用的启动脚本,该脚本将运行在主进程中,请保证你拖进Electron的文件夹下能找到这个文件

//引入electron
const electron = require('electron');
//app控制整个Electron的声明周期
const app =electron.app;
//创建一个本地的窗口
const BrowserWindow = electron.BrowserWindow
//保持一个全局的窗口对象,可以不显示,如果没有这个对象,窗口点击关闭的时候,js对象会被gc干掉
let mainWindow;

function createWindow(){
    mainWindow = new BrowserWindow({
        width: 800, 
        height: 600
    })
    //加载静态资源
    mainWindow.loadURL('file://' + __dirname + '/index.html');

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

//生命周期的函数定义
//这里好好看api http://electron.atom.io/docs/api/app/
app.on("ready",createWindow)

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  if (mainWindow === null) {
    createWindow()
  }
})

index.html做为静态资源被加载,可以引用一些mvvm,比如一会儿我会引入vue,也可以引入three.js

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
	</head>
	<body>
		<h1>Hello world</h1>

	</body>
</html>

3.3.启动

拖拽文件夹到electron.exe中,就可以看到下面的效果

electron1.jpg

3.4.搞点事

可以尝试一下,在package.json中添加依赖,或者在index.html中

mainWindow = new BrowserWindow({
    width: 800, 
    height: 600,
    frame: false
})

API

4.1 MENU & 设置快捷键

引入menu有两种方法,写在HTMl里,或者写在main.js这样的文件里 我个人喜欢后者,因为HTML说不定会别的地方会用,上来就报错不太好 推荐阅读menu和menuiteam的官方API和例子 http://electron.atom.io/docs/api/menu/ http://electron.atom.io/docs/api/menu-item/

先看代码

//引入menu
let Menu = electron.Menu;
//引入menuIteam
let MenuItem = electron.MenuItem
//创建一个menuIteam
const menuIteam_first = new MenuItem({
	label:"Electron",
	submenu: [
		{
        	//需要通过cmd来启动
			label:"show sth in cmd",
			click(){
				console.log("clickLabel")
			}
		},
		{
        	//创建一个新的窗口
			label:"new window",
			accelerator:"CmdOrCtrl+N",
			role:"",
			click(){
				let newwindow = new BrowserWindow({
					width: 400, 
      				height: 300,
					resizable:false
				})
				newwindow.loadURL('file://' + __dirname + '/source/electron1.jpg');
				newwindow.on("closed",function(){
					newwindow = null
				})
			}
		},
		{
        	//可以看到一个选中的选项
			label: 'checked', 
			type: 'checkbox', 
			checked: true
		},
		{
        	//所有menuIteam的label都可以有submenu
			label: 'Gender', 
			submenu:[
				{
					label:"male",
					type:"radio",
					checked:true
				},
				{
					label:"female",
					type:"radio",
					checked:false
				},
				{
					label:"computer",
					type:"radio",
					checked:true
				}
			]
		},

		{
        	//只写role可以调用一些默认的设置,比如这个是全屏
			role: 'togglefullscreen'
		},
		{
        	//accelerator是定义快捷键,click可以按自己需要写
			label: 'Developer Tools',
			accelerator: process.platform === 'darwin' ? 'CmdOrCtrl+I' : 'CmdOrCtrl+I',
			click(item, focusedWindow) {
			if (focusedWindow)
				focusedWindow.webContents.toggleDevTools();
			}
		},
		{	
        	//可以调用role默认的同时重写一些需要的内容
			label:"GOODBYE",
			role:"quit",
			accelerator:"CmdOrCtrl+Q"
		}
	]
});

解释一下: 创建menu很简单三步就能说清楚 1、创建一个menu对象,定义好label的叫什么,往里面塞menuIteam 2、定义你的menuIteam,可以用role简化,也可以不写role,自己写click()函数 3、挂在到你的窗口上

注意,窗口的宽和高是整个视窗的,间距边框和工具栏才是html的宽和高,要是不想麻烦,give up这部分,用html写好然后调用系统的js接口吧

4.2 最小化图标

QQ平时是可以最小化到右下角的,用Electron来实现很容易 但是请确认你已经读懂了Menu部分

还是推荐先看API http://electron.atom.io/docs/api/tray

然后看代码:

//引入Tray
let Tray = electron.Tray;
let tray = null;

function createWindow(){
	mainWindow = new BrowserWindow({
		width: 800, 
		height: 600
	})
	//加载静态资源
	mainWindow.loadURL('file://' + __dirname + '/index.html');

	let image = nativeImage.createFromPath('/source/electron1.jpg');

	tray = new Tray(image);

	const contextMenu = Menu.buildFromTemplate([
		
		{
			label:"show",
			click(){
				mainWindow.show()
			}
		},
		{
			label:"Exit",
			role:"quit"
		}
	]);
	// tray.setToolTip('This is my application.')
	tray.setContextMenu(contextMenu)

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

}

创建一个右下角小图标很简单,两步即可 1、声明一个全局的tray对象,然后在你创建主窗口的初始化函数中,给它一个默认图标 2、创建一个menu,这个步骤跟刚才一样,记得绑定到tray上

注意一点:tray的图片需要nativeImage格式,具体什么是nativeImage看这里,如果你的图标type Error了,那么可以使用electron提供的一个转换函数把i的图片转换一下

const nativeImage = electron.nativeImage;

4.3 ipcMain

ipcMain是用来让mainWindow和创建的window们传递数据

//main.js
ipcMain.on('asynchronous-message', (event, arg) => {
  console.log(arg);  // prints "ping"
  event.sender.send('asynchronous-reply', 'pong');
});

ipcMain.on('synchronous-message', (event, arg) => {
  console.log(arg);  // prints "ping"
  event.returnValue = 'pong';
});

<script>
    const {ipcRenderer} = require('electron');

    console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); 

    ipcRenderer.on('asynchronous-reply', (event, arg) => {
        console.log(arg); // prints "pong"
    });

    ipcRenderer.send('asynchronous-message', 'ping');
</script>

electron2.jpg

解释一下: 1.在主窗口中定义ipcMain,注册一些同步or异步事件来处理收到的事件 2.在需要发消息的窗口,发送消息 3.如果是异步的,在发送消息的窗口,定义接收信息事件

4.4 桌面捕获

占位,困

End

就使用结果来看,视频,音频等流媒体的获取我还在研究,其他的模块Electron的表现还是相当不错的,至少我想到的桌面开发需求还是都有的。即使没有,咱们还有node嘛,多走一层就是了。

需求场景我觉得还是蛮多的,比如ERP,CMS都这种通过网站打开的在线办公系统比较依赖网站,用这个封装一下,可以免去很多初级用户(交互定义上的)的使用风险

强交互的场景还是比较需要桌面版的,比如Tower、钉钉这样的都有需求

我建议程序员们现在可以上手玩,自己做一个集成软件,比如我接下来会将监控&管理工程文件,md的一些文档的预览,发周报的脚本,爬虫等等集成到一起,做一个统一入口

欢迎各位指正&交流

杜绝无脑黑

推荐阅读 官网的一篇demo的介绍

回到顶部