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中,就可以看到下面的效果
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>
解释一下: 1.在主窗口中定义ipcMain,注册一些同步or异步事件来处理收到的事件 2.在需要发消息的窗口,发送消息 3.如果是异步的,在发送消息的窗口,定义接收信息事件
4.4 桌面捕获
占位,困
End
就使用结果来看,视频,音频等流媒体的获取我还在研究,其他的模块Electron的表现还是相当不错的,至少我想到的桌面开发需求还是都有的。即使没有,咱们还有node嘛,多走一层就是了。
需求场景我觉得还是蛮多的,比如ERP,CMS都这种通过网站打开的在线办公系统比较依赖网站,用这个封装一下,可以免去很多初级用户(交互定义上的)的使用风险
强交互的场景还是比较需要桌面版的,比如Tower、钉钉这样的都有需求
我建议程序员们现在可以上手玩,自己做一个集成软件,比如我接下来会将监控&管理工程文件,md的一些文档的预览,发周报的脚本,爬虫等等集成到一起,做一个统一入口
欢迎各位指正&交流
杜绝无脑黑
推荐阅读 官网的一篇demo的介绍