Electron是什么

​Electron 是一个由 GitHub 开发的开源库,经过将 Chromium) 和Node.js 组兼并运用 HTML,CSS 和 JavaScript 进行构建 Mac,Windows,和 Linux 跨渠道桌面运用程序。

原理:
上面已将说了,Electron 经过将 Chromium 和 Node.js 组合到单个 runtime 中来完成的.

nodejs:

假如你不知道 node.js,那还等什么快戳这儿,看一看世界上最温柔可爱的语言。它借助于 Google 的 V8 引擎,Node.js 是一个可以在服务器端运转 JavaScript 的开放源代码、跨渠道 JavaScript 运转环境,更多解释请戳维基百科。

Chromium:

Chromium 或许你没听说过,可是你一定听说过 chrome 吧!Chromium 是 Google 的开源浏览器,是 chrome 背面的那个不太稳定更新快的兄弟版,详情戳这儿。

组合:

Electron 创立的运用运用网页作为其 GUI ,因而你可以将其当成由 JavaScript 控制的迷你精简版Chromium 浏览器。也可以将 Electron 当成 node.js 变体,只不过它更专心于桌面运用而非 Web 服务器。在 Electron 中, 把 package.json 中设定的 main 脚本的地点进程称为 主进程。这个进程中运转的脚本也可经过创立网页这种方式来展现其 GUI。 由于 Electron 是经过 Chromium 来显示页面,所以 Chromium 自带的多进程架构也一同被利用。这样每个页面都运转着一个独立的进程,它们被统称为 烘托进程。一般来说,浏览器中的网页会被限制在沙盒环境中运转而且不允许拜访体系原生资源。可是由于 Eelectron 用户可在页面中调用 Node.js API,所以可以和底层操作体系直接交互。

优缺陷?
总之,长处必定大于缺陷。

长处:

便利快捷的开发桌面运用,跨渠道,对前端开发者友爱,活泼的社区,丰厚的api……

缺陷:

性能必定比不上原生的桌面运用,发布的包貌似有一点点大。

OK,接下来开端…………………………………………………

一、快速创立react项目

首要装置好GIT和nodejs,装置好nodejs一起也装置好了npm

这是运用Facebook开发的reate-react-app 来快速创立一个 react 项目(命名为react-electron)。

# 装置 create-react-app 指令,假如已将装置请忽略
npm install -g create-react-app
# 创立 react项目
create-react-app react-electron
# 发动项目( create-react-app 真的超级便利啊)
cd react-electron && npm start

相关装备
react-electron 根目录(不是 src 目录)下面新建 main.js 文件,这个文件和 electron-quick-start 中的官方默许 main.js 几乎一模一样,只修正了加载运用这入口这一个当地:

// 引进electron并创立一个Browserwindow
const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
// 坚持window目标的大局引证,防止JavaScript目标被废物收回时,窗口被主动封闭.
let mainWindow
function createWindow () {
//创立浏览器窗口,宽高自定义详细巨细你开心就好
mainWindow = new BrowserWindow({width: 800, height: 600})
  /* 
   * 加载运用-----  electron-quick-start中默许的加载入口
    mainWindow.loadURL(url.format({
      pathname: path.join(__dirname, './build/index.html'),
      protocol: 'file:',
      slashes: true
    }))
  */
  // 加载运用----适用于 react 项目
  mainWindow.loadURL('http://localhost:3000/');
  // 翻开开发者东西,默许不翻开
  // mainWindow.webContents.openDevTools()
  // 封闭window时触发下列事情.
  mainWindow.on('closed', function () {
    mainWindow = null
  })
}
// 当 Electron 完成初始化并预备创立浏览器窗口时调用此方法
app.on('ready', createWindow)
// 一切窗口封闭时退出运用.
app.on('window-all-closed', function () {
  // macOS中除非用户按下 `Cmd + Q` 显式退出,否则运用与菜单栏始终处于活动状况.
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
app.on('activate', function () {
   // macOS中点击Dock图标时没有已翻开的其他运用窗口时,则一般在运用中重建一个窗口
  if (mainWindow === null) {
    createWindow()
  }
})
// 你可以在这个脚本中续写或者运用require引进独立的js文件. 

装备 package.json

{
  "name": "knownsec-fed",
  "version": "0.1.0",
  "private": true,
  "main": "main.js", // 这儿 装备发动文件
  "homepage":".", // 这儿
  "dependencies": {
    "electron": "^1.7.10",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-scripts": "1.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "electron-start": "electron ." // 这儿 装备electron的start,区别于web端的start
  }
}

发动Electron

npm start	//发动react运用
electron .		//发动electron

其实很明显,项目的根本构成还是依据react来进行开发的,只是在原有的chroms根底下换做了electron进行开发,当然也可以在main.js中装备electron-reloader进行项目热更新的装备。

npm i electron-reloader
//热加载
try {
    require('electron-reloader')(module)
} catch (_) {}

支持热调试,当你修正代码后,桌面运用也将会重新更新。

react路由装备与主进程合作通讯

像默许react的项目是经过浏览器url进行页面的切换,假如在electron中想要到达点击某个按钮翻开一个烘托进程而且加载指定的路由首要需求装备react路由,这儿我以三个路由进行示例:

route.js 路由文件

import Menu from './components/Menu'
import Shopping from './components/Shopping'
import Footer from './components/Footer'
const routes = [
    {
        name: 'menu',
        path: '/menu',
        component: Menu
    },
    {
        name: 'shopping',
        path: '/shopping',
        component: Shopping
    },
    {
        name: 'footer',
        path: '/footer',
        component: Footer
    }
]
export default routes

在App.js中引进并装备

return (
      <BrowserRouter>
        <h1 onClick={openRender}>首页</h1>
        <div className="App">
            <Link to = '/menu'>Menu</Link>
            <Link to = '/shopping'>Shopping</Link>
            <Routes>
                {
                    routes.map((item, key) => {
                        return (
                            <Route key = {key} path ={item.path} element ={<item.component/>}></Route>
                        )
                    })
                }
            </Routes>
        </div>
      </BrowserRouter>
  );

现在有一个button,点击后希望敞开一个烘托进程而且加载Footer组件,因而需求在App.js中运用ipcRenderer进行发布订阅发射事情。

import './App.css';
import {Route, Routes, Link, BrowserRouter} from 'react-router-dom'
import routes from './Route'
const {ipcRenderer} = window.require('electron')		//引进electron模块
function App() {
	//触发点击事情,发射给electron主进程
    const openRender = () => {
        ipcRenderer.send('openRender', {
            width: 400,
            height: 400
        })
    }
  return (
      <BrowserRouter>
        <h1 onClick={openRender}>首页</h1>
        <div className="App">
            <Link to = '/menu'>Menu</Link>
            <Link to = '/shopping'>Shopping</Link>
            <Routes>
                {
                    routes.map((item, key) => {
                        return (
                            <Route key = {key} path ={item.path} element ={<item.component/>}></Route>
                        )
                    })
                }
            </Routes>
        </div>
      </BrowserRouter>
  );
}
export default App;

在主进程main.js中接收并敞开烘托进程

ipcMain.on('openRender', (event, avg) => {
    let renderWindow = null;
    const {width, height} = avg
    renderWindow = new BrowserWindow({
        width,
        height,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
    })
    renderWindow.webContents.loadURL('http://localhost:3000/footer')
})

这样,就完成了react和electron的交互了,敞开了一个烘托进程一起加载了footer路由

三、打包react项目

首要修正main.js, 由于现在你要将 react 项目打包在 build 文件夹下面,所以加载运用途改成如下!当然也可在某个装备文件里边装备是否归于开发,此处用if判断一下从未进行选择执行哪段加载运用代码。可是这儿为了简便,暂时运用直接修正的方式:

// 加载运用----react 打包
mainWindow.loadURL(url.format({
  pathname: path.join(__dirname, './build/index.html'),
  protocol: 'file:',
  slashes: true
}))
// 加载运用----适用于 react 开发时项目
// mainWindow.loadURL('http://localhost:3000/');

默许情况下,homepage 是 http://localhost:3000,build 后,一切资源文件路径都是 /static,而 Electron 调用的入口是 file :协议,/static 就会定位到根目录去,所以找不到静态文件。在 package.json 文件中添加 homepage 字段并设置为”.”后,就可以开端打包了。

npm run-script build

四、打包electron

常用打包插件
装置electron-packager

# knownsec-fed目录下装置electron-packager包
npm install electron-packager --save-dev
# 装置electron-packager指令
npm install electron-packager -g

打包指令:

electron-packager <location of project> <name of project> <platform> <architecture> <electron version> <optional options>

location of project: 项目的本地地址,此处我这边是 ~/knownsec-fed
location of project: 项目名称,此处是 knownsec-fed
platform: 打包成的渠道
architecture: 运用 x86 还是 x64 还是两个架构都用
electron version: electron 的版别

所以,依据我这边的情况在 package.json 文件的在 scripts 中加上如下代码:

"package": "electron-packager /home/react-electron react-electron --all --out ~/ --electron-version 2.0.6"

开端打包:

npm run-script package

五、结束语

由于作业的原因需求用到electron。经过一周时刻的研究和学习,可以得出electron确实是一个跨渠道开发运用的利器,经过web开发就能完成wirte once, run every where的理念。很棒。

在electron里边可以调用nodejs几乎一切的功用,当然前提是需求require nodejs的包;
在react的js页面或者公司项目用到的Ant Design的一些js页面需求用到electron时候,经过官方的

const electron = require('electron')

语句并不能成功引进,此刻需求经过

const electron = window.require('electron')

引进;

还有,最最最重要的一点!!!!开发时候一般都是在main中经过react项目的URL去热调试运用,BUT!!此刻请在electron生成的窗口中进行调试!!假如只在浏览器的页面检查效果,会提示electron的模块无法导入,无论你用啥方法!

最后,再提一点自己的感受。运用nodejs的fs包和electron的dialog、app类可以首要调用不同渠道的文件选择器和一些特别文件夹的的功用,比如说桌面、用户默许数据文件夹的修正。这儿不多作描绘了。~~

本文部分引进此篇博客的观点,谢谢作者的慷慨总结!!