Electron 是什么?

你只要记住下面这两句话就可以对 Electron 有个基本了解:

  • Electron 是由 Github 开发的开源框架
  • 它允许开发者使用 Web 技术构建跨平台的桌面应用

::: tip Electron = Chromium + Node.js + Native API :::

  • Chromium : 为 Electron 提供了强大的 UI 能力,可以不考虑兼容性的情况下,利用强大的 Web 生态来开发界面。

  • Node.js :让 Electron 有了底层的操作能力,比如文件的读写,甚至是集成 C++等等操作,并可以使用大量开源的 npm 包来完成开发需求。

  • Native API : Native API 让 Electron 有了跨平台和桌面端的原生能力,比如说它有统一的原生界面,窗口、托盘这些。

通过三者的巧妙组合,我们开发应用变的十分高效。

起步

新建一个文件夹

 mkdir demo1
 npm init -y
 touch main.js
 touch index.html

安装依赖

cnpm i electron -D

示例文件

// main.js
const { app, BrowserWindow } = require("electron");
let mainWindow = null;
app.on("ready", () => {
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 1000,
    title: "main process custom window", // 当使用loadFile引入html文件时,html的title元素会覆盖此参数。
    fullscreen: false,
    alwaysOnTop: false, // 始终固定在最顶层
    closable: true,
    frame: true,
    transparent: false, // 通过将 transparent 选项设置为 true, 还可以使无框窗口透明。
    skipTaskbar: false, // 是否在任务栏隐藏
    webPreferences: {
      devTools: true, // 禁止任何方式打开devTools
      nodeIntegration: true,
      enableRemoteModule: true
    }
  });
  mainWindow.loadFile("./index.html", { query: { name: "zjc" } });
  mainWindow.on("close", () => {
    mainWindow = null;
  });
});
// package.json
{
  "name": "demo1",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "dev": "electron .",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^11.1.1"
  }
}

app

控制应用程序的事件生命周期。

事件

app 对象会发出以下事件:

事件: ‘ready’

当 Electron 完成初始化时,发出一次。

事件: ‘window-all-closed’

当所有的窗口都被关闭时触发。

事件: ‘before-quit’

当应用程序开始关闭关闭窗口之前触发。

事件: ‘will-quit’

当所有窗口都已关闭并且应用程序即将退出时触发。

事件: ‘will-quit’

应用程序退出时触发。

BrowserWindow

创建和控制浏览器窗口。(主进程)

new BrowserWindow([options])

  • optionsObject (可选)
    • alwaysOnTop Boolean (可选) - 窗口是否固定在屏幕最上方。默认值为 false。
    • width Integer (可选) - 窗口的宽度(以像素为宽度)。 默认值为 800
    • height Integer (可选) - 窗口的高度(以像素为单位)。 默认值为 600
    • x Interger (可选) - (必选 如果使用了 y) 窗口相对于屏幕左侧的偏移量。 默认值为将窗口居中。
    • y Integer (可选) - (必选 如果使用了 x) 窗口相对于屏幕顶端的偏移量。 默认值为将窗口居中。
    • center Boolean (可选) - 窗口在屏幕居中。默认值为 true。
    • frame Boolean (可选) - 是否创建无边界窗口(无边框窗口是不带外壳(包括窗口边框、工具栏等),只含有网页内容的窗口。)。默认值为 false。
    • transparent Boolean (可选) 是否设置窗口透明。默认值为 false。
    • fullscreen Boolean (可选) - 窗口是否全屏。默认值为 false。
    • resizable Boolean (可选) - 窗口是否可被伸缩。默认值为 true。
    • movable Boolean (可选) - 窗口是否可被拖动。默认值为 true。
    • skipTaskbar Boolean (可选) - 是否在任务栏隐藏。默认值为 false 不隐藏。
    • title String(可选) - 默认窗口标题 默认为"Electron"。 如果由loadURL()加载的 HTML 文件中含有标签<title>,此属性将被忽略。
    • webPreferences Object (可选) - 配置页面的其他特性
      • devTools Boolean (可选) - 是否开启 DevTools. 如果设置为 false, 则无法使用。默认值为 true。
      • nodeIntegration Boolean (可选) - 是否在渲染进程中集成 Node. 如果设置为 false, 则在渲染进程中无法使用 Node 相关 Api。默认值为 false。
      • enableRemoteModule Boolean (可选) - 是否允许调用远程模块. 默认值为 false.

实例方法

使用 new BrowserWindow 创建的对象具有以下实例方法:

  • win.loadFile(filePath[,options])

    • filePath String - 加载的页面路径
    • options Object (可选)
      • query Record<String, String> (optional) - Passed to url.format().
      • search String (可选) - 传递给 url.format().
      • hash String (可选) - 传递给 url.format().

等同于webContents.loadFile, filePath指的是以项目的根目录为起点的相对路径

  • win.loadURL(url[,options])
    • url String - 加载的 uri 地址
    • options Object (可选)
      • httpReferrer (String Referrer) (optional) - An HTTP Referrer URL.
      • userAgent String (可选) - 发起请求的 userAgent.

url 可以是远程地址 (例如 http://),也可以是 file:// 协议的本地 HTML 文件的路径.

为了确保文件网址格式正确, 建议使用 Node 的 url.format 方法:

const url = require("url").format({
  protocol: "file",
  slashes: true,
  pathname: require("path").join(__dirname, "index.html")
});

win.loadURL(url);
  • win.reload()

webContents.reload 相同

调试

在 vscode 中调试主进程的代码

在工作台根目录下新建.vscode/lanuch.json 文件。并写入如下代码

{
  // 使用 IntelliSense 了解相关属性。
  // 悬停以查看现有属性的描述。
  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Electron Main",
      "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
      "program": "${workspaceFolder}/main.js",
      "protocol": "inspector" //添加默认的协议是legacy,这个协议导致不进入断点
    }
  ]
}