暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Electron开发概述

Sumslack团队 2019-06-16
1040

概述

Electron
是由Github
开发,用HTML
CSS
JavaScript
来构建跨平台桌面应用程序的一个开源库。 Electron
通过将Chromium
Node.js
合并到同一个运行时环境中,并将其打包为Mac
Windows
Linux
系统下的应用来实现这一目的。
Electron
运行package.json
main
脚本的进程被称为主进程,在主进程中可以通过创建BrowserWindow
来展示用户界面,Electron
只有一个主进程,每个运行在Chromium
中的Web页面是独立的渲染进程。Electron
可与操作系统做底层交互。在渲染进程中调用GUI原生API是不被允许的,如果要调用这些API,要与主进程通信,在主进程中处理。在Electron
中,有些API针对主进程,有些则针对渲染进程,具体请查看文档。Electron
通过remote模块暴露一些通常只能在主进程中获取到的API。 为了在渲染进程中创建一个BrowserWindow
的实例,我们通常使用remote模块为中间件。在Electron
的主进程和渲染进程中,都可以调用nodeJS

它可以用来干嘛

以下业务场景下,您可以考虑使用Electron

  • 瘦客户端,跨平台,需支持Windows,Linux和Mac的客户端程序;

  • 小程序、脚本类开发工具,比如目前市面上的支付宝小程序和头条小程序,使用的都是Electron
    ,而微信小程序开发工具使用的nw.js

  • 基于Web的刷分工具;

  • 其他;

优势和比较

体积适中,比CEF小很多,运行速度快,能与底层操作系统交互,扩展原生接口方便,跨平台,不支持XP,必须是Windows 7或以上,成功案例多,如Slack,Visual Studio
Code,Atom等。支持NodeJS,入手容易,与nw.js相比,Electron发展更快,bug更少,贡献者更多,社区更活跃。

常见问题

主进程的常用API

  • 在渲染进程中可以判断在线离线情况:navigator.onLine
    ,如果要在主进程中处理,可以通过渲染进程向主进程发送消息。

  • 主进程中可以通过win.setProgressBar(0.5)
    设置任务栏图标的进度;

  • BrowserWindow
    类控制浏览器行为,方法比较常用,比如setSize用来重置窗口大小(登录=》主窗口),具体api详见:https://electronjs.org/docs/api/browser-window

  • 可以在主进程或渲染进程中调用剪贴板操作:

const { clipboard } = require('electron');
clipboard.writeText('string');//writeHTML,writeImage,writeRTF,writeBookmark,write
clipboard.readText('selection'); //readHTML,readImage,readRTF,readBookmark()

  • 可以在主线程中查看cookies:

session.defaultSession.cookies.get({ url: 'http://www.github.com' }, (error, cookies) => {
  console.log(error, cookies)
})

  • 可以在主线程中调用系统对话框,比如文件保存对话框,文件打开对话框等,如果要在渲染进程中打开,请使用remote;

  • 可以在主线程中注册快捷键:

const { app, globalShortcut } = require('electron')
app.on('ready'() => {
  const ret = globalShortcut.register('CommandOrControl+X'() => {
    console.log('CommandOrControl+X is pressed')
  })
  if (!ret) {
    console.log('registration failed')
  }
  console.log(globalShortcut.isRegistered('CommandOrControl+X'))
})
app.on('will-quit'() => {
  globalShortcut.unregister('CommandOrControl+X')
  globalShortcut.unregisterAll()
})

  • 菜单只允许在主线程中通过new Menu()
    创建,要在渲染进程中创建菜单,请使用remote
    ,如下:

<!-- index.html -->
<script>
const { remote } = require('electron')
const { Menu, MenuItem } = remote

const menu = new Menu()
menu.append(new MenuItem({ label'MenuItem1', click() { console.log('item 1 clicked') } }))
menu.append(new MenuItem({ type'separator' }))
menu.append(new MenuItem({ label'MenuItem2'type'checkbox'checkedtrue }))

window.addEventListener('contextmenu', (e) => {
  e.preventDefault()
  menu.popup({ window: remote.getCurrentWindow() })
}, false)
</script>

  • remote
    模块为渲染进程和主进程通信提供一种简单方法,如:const { BrowserWindow } = require('electron').remote
    ,以上BrowserWindow
    是远程对象。它还有其他常见的方法,如:返回当前网页窗口getCurrentWindow()
    ,返回当前网页内容:getCurrentWebContents()
    ,获取全局变量getGlobal()
    ,主进程中的process
    对象等。

利用remote在渲染进程中调用主进程API

//这样写在渲染进程中时行得通的,但是在主进程中是'未定义'
const { remote } = require('electron')
const { BrowserWindow } = remote

const win = new BrowserWindow()

网络处理:http和websocket

在渲染进程中,可以通过http模块处理网络请求:

const http = require('http');
var _param = JSON.stringify({
    script:encodeURIComponent(_script)
});
const request = http.request({
    method:"POST",
    host:'localhost',
    port:8080,
    path:'/spider/base/previewScript',
    headers:{
        'Content-Type''application/json',
        'Content-Length': _param.length,
        'token':'xxx'
    }
    },(res) => {
        res.on('data'(chunk) => {
        console.log(`BODY: ${chunk}`)
    })
    res.on('end'() => {
        console.log('No more data in response.')
    })
    });
        request.on('error'(e) => {
        console.log(`problem with request: ${e.message}`);
    });
request.write(_param);
request.end();

具体http的详细API可参考:https://nodejs.org/dist/latest-v4.x/docs/api/http.html#http_http_get_options_callback

也可以使用进程间通讯,将渲染进程中的ajax请求发往主进程ClientRequest
,主进程执行后利用回调函数到渲染进程,这种是官方推荐用法。详见:https://electronjs.org/docs/api/client-request

至于WebSocket,可以使用SockJS
+Stomp
,如下:

 var sock = new SockJS("http://localhost:8080/websocket-spider?token=xxx");
 var stompClient = Stomp.over(sock);
 var headers = {
     a:"1"
 };
 stompClient.connect(headers,(frame) => {
 stompClient.subscribe('频道名'(msg) => {
        ......
     });
     }, (err) => {
         // 连接发生错误时的处理函数
         console.log(err);
     });
 });

主进程和渲染进程通信

渲染进程可以向主进程发送消息,以便让主进程调用相应的API,在渲染进程中:

//发送同步消息到主进程
const { ipcRenderer } = require('electron')
console.log(ipcRenderer.sendSync('synchronous-message''ping')) // prints "pong"
//接收渲染进程向主进程发送异步消息的回调
ipcRenderer.on('asynchronous-reply'(event, arg) => {
  console.log(arg) // prints "pong"
})
//发送异步消息到主进程
ipcRenderer.send('asynchronous-message''ping')

在主进程中:

//接收来自渲染进程的异步消息
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'
})

收集程序的崩溃报告

收集日志的服务端可以由socorro
mini-breakpad-server
构建,客户端代码如下:

const { crashReporter } = require('electron')

crashReporter.start({
  productName'YourName',
  companyName'YourCompany',
  submitURL'https://your-domain.com/url-to-submit',
  uploadToServertrue
})


你可以继续阅读:


一款自动生成后台代码的管理系统的设计与实现 “大”中台,“小”前端的架构演变| 云服务平台中推送服务的设计与实现 | 对微服务的理解以及实现一套微服务对外发布API管理平台 | 项目开发中常用的设计模式整理 | 异构语言调用平台的设计与实现 | 大话正则表达式 | 云API平台的设计与实现 | 个税改了,工资少了,不要慌!文末附计算器


关注我们的公众号 

长按识别二维码关注我们

文章转载自Sumslack团队,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论