# 学习electron

# 运行第一个桌面端程序

git clone https://github.com/electron/electron-quick-start

cd electron-quick-start

# 国内无法连接上, 使用淘宝镜像(使用前请先安装淘宝镜像)
npm config set ELECTRON_MIRROR https://npm.taobao.org/mirrors/electron/

npm install

npm start

1
2
3
4
5
6
7
8
9
10
11

# 相比于传统的web页面,electron 该如何来调试呢

在此以前, 我们需要了解 一个electron程序由有且只有一个主进程和若干多个渲染进程组成

主进程由 main.js 中的代码组成,渲染进程由 html 后缀的代码组成,比如上面的示例代码中的 index.html

# 渲染进程的调试

当你成功启动electron程序时,会弹出一个页面。页面上有若干的导航栏, 点击 View,再点击 Toggle Developer Tools。这时就会弹出和谷歌浏览器一样的 console 调试器。当然你也可以使用快捷键 Ctrl + Shift + i 来打开调试器。

# 主进程的调试(使用浏览器进行调试)

这时我们需要修改 package.json,设置 5858 端口。然后再重新运行程序。



 



  "scripts": {
    -- "start": "electron ."
    ++ "start": "electron --inspect=5858 ."
  },

1
2
3
4
5

接着我们需要打开谷歌浏览器,输入网址 chrome://inspect/

在打开的界面中我们可以看到两个按钮 Port forwarding...Configure...

点击 Configure... 会出现一个输入 ip 和 port 的弹窗。

我们输入 localhost:5858。 点击 done

重新运行程序。

最后界面如下: chrome://inspect/图

出现了 Remote Target 即为成功。点击 inspect ,就会出现 debbug 窗口。

然后点击 Sources 源代码标签页。就会出现 main.js 中的代码。这时候你就可以开始在 main.js 断点代码了。

如果点击Sources 源代码标签页并未出现main.js 中的代码,那就点击三个点, 点击 Open file去搜索文件,输入 main.js即可搜索到。

调试界面图

# 主进程的调试(使用vs code工具进行调试)

点击 vs code 右边导航栏中的运行标签, 也可以使用快捷键 Ctrl + Shift + D。这时就会出现调试界面, 点击绿色箭头就可以开始调试,这时你就可以去 main.js 中设置断点了。

vscode图

# 看下文档,了解下相应的api

看完文档,很多都忘记了。但是却记住了下面几条重要的东西:

  1. Node.js 中所有内置模块和第三方模块 在 Electron 中都支持。
  2. 注意:要从渲染过程中访问Node.js API,您需要设置 nodeIntegration 选项为 true。

Node.js API 包含了 require 模块, process 信息, fs 模块,path 模块等。所以我可以理解, 这个一定要设置。

  1. Electron API是根据流程类型分配的。这意味这某些模块或API只能在主进程或渲染进程使用,有些可以在两者中使用。Electron 的 API 文档指明了每个模块可以使用的过程。所以有时候你发现API没用,那看下文档吧。

  2. 在 Electron 中,通信是十分重要的。比如主进程和渲染进程通信,不同的渲染进程之间的通信。而通信有两种方式进行通信。分别是 ipcMainipcRenderer 通信模块。下面有个渲染进程和主进程通信的示例:

// 主进程
const { ipcMain } = require('electron')

ipcMain.handle('tel', (evidence, ...args) => {

})

// 在渲染进程中
const { ipcRenderer } = require('electron')

ipcRenderer.invotrake('tel', ...args)

1
2
3
4
5
6
7
8
9
10
11
12

可以发现和 events 通信有点相似。任意命名一个相同的字符串, 通过 ipcMain 创建监听器, ipcRenderer 触发监听器。

  1. 主进程和渲染进程的区别,只有主进程可以和 GUI 或底层系统打交道, 而渲染进程除了额外能够使用 Node.js 能力之外,与普通网页没区别。

看了下文档,太多了,简单说一下大概功能:

主进程模块

  • app -> 控制应用程序的事件生命周期,相当于整个程序的实例。
  • autoUpdater -> 控制程序的自动更新
  • BrowserView -> 创建新页面的
  • BrowserWindow -> 创建和控制浏览器窗口
  • contentTracing -> 内容跟踪,以发现性能瓶颈和缓慢的操作
  • dialog -> 显示用于打开和保存文件、警报等的本机系统对话框
  • globalShortcut -> 创建全局快捷键方式
  • inAppPurchase -> Mac App Store中的应用内购买相关
  • ipcMain -> 通信模块,从主进程到渲染进程的异步通信
  • Menu -> 顶部菜单相关
  • MenuItem -> 顶部菜单项相关
  • net -> 使用Chromium的原生网络库发出HTTP / HTTPS请求
  • netLog -> 网络事件日志的记录
  • nativeTheme -> 读取并响应Chromium本地色彩主题中的变化
  • Notification -> 创建OS(操作系统)桌面通知,比如有新的版本要更新了,有人发消息给你了等等...
  • powerMonitor -> 监视电源状态的改变
  • powerSaveBlocker -> 阻止系统进入低功耗 (休眠) 模式
  • protocol -> 注册自定义协议并拦截基于现有协议的请求
  • screen -> 检索有关屏幕大小、显示器、光标位置等的信息
  • session -> 管理浏览器会话、cookie、缓存、代理设置等
  • systemPreferences -> 获取system preferences
  • TouchBar -> 为原生macOS应用创建TouchBar布局
  • Tray -> 添加图标和上下文菜单到系统通知区
  • webContents -> 渲染以及控制 web 页面

渲染进程模块

  • desktopCapturer -> 可以访问那些用于从桌面上捕获音频和视频的媒体源信息
  • ipcRenderer -> 从渲染器进程到主进程的异步通信
  • remote -> 可以让我们在在渲染进程中使用主进程模块
  • webFrame -> 自定义渲染当前网页

两种进程都可以用模块

  • clipboard -> 在系统剪贴板上执行复制和粘贴操作
  • crashReporter -> 将崩溃日志提交给远程服务器
  • nativeImage -> 使用 PNG 或 JPG 文件创建托盘、dock和应用程序图标
  • shell -> 使用默认应用程序管理文件和 url

我们是需要大概了解下所有的api的,以便在开发的时候知道去哪查看文档!

# 现在我们可以开始做一个项目了

想了很久, 就做一个个人管理器吧, 就是类似于一个windows 系统,然后很多功能集成在里面。没事,慢慢写...

因为写着写着你就会发现,好多报错,哈哈哈

# 1. 好歹是做过很多项目的, 得先把文件结构分好。

首先分出一个文件夹views存放web界面的,这个文件夹将专门管理渲染界面。

views 下面的每一个文件夹都有三个文件,分别是 html, css, renderer.js 文件,对应着一个渲染进程。

如下图所示:

文件结构目录图

记住: 这时你也要更改 main.js 中的路径,它第一次打开界面所指路径。

// main.js

-- mainWindow.loadFile('index.html')
++ mainWindow.loadFile('./views/index/index.html')
1
2
3
4

然后再创建一些别的文件夹对应别的功能,比如 config 全局配置,utils 工具类,ipc 进程通信 等对应别的功能。

# 2. 开始写UI吧

然后就发现了一个问题,在 html 文件中 style 标签和元素的 style 属性一旦写了就直接报错了。

// 报错信息

Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". 
Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is 
required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
1
2
3
4
5

当然你也用 css 文件来避免这个报错, 不使用style 标签和元素的 style 属性。

但是也有别的解决办法:

修改下 html 文件的 meta 标签即可。

<!-- ./views/index/index.html --> 
-- <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
++ <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline'; script-src 'self'">
1
2
3

# 3. 还是先整合vue进去吧

突然还是发现 vue 够香,所以使用了 electron-vue 搭建项目。

electron-vue 文档 https://simulatedgreg.gitbooks.io/electron-vue/content/cn/ (opens new window)

# 安装 vue-cli 和 脚手架样板代码
npm install -g vue-cli
vue init simulatedgreg/electron-vue my-project

# 安装依赖并运行你的程序
cd my-project
yarn # 或者 npm install
yarn run dev # 或者 npm run dev
1
2
3
4
5
6
7
8

安装完之后就可以开始运行了, 运行时出现了一个问题:

ReferenceError: process is not defined
1

解决方案:

// 文件目录 .electron-vue/webpack.web.config.js
plugins: [
    new VueLoaderPlugin(),
    new MiniCssExtractPlugin({filename: 'styles.css'}),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: path.resolve(__dirname, '../src/index.ejs'),
     ++ templateParameters(compilation, assets, options) {
     ++  return {
     ++     compilation: compilation,
     ++     webpack: compilation.getStats().toJson(),
     ++     webpackConfig: compilation.options,
     ++     htmlWebpackPlugin: {
     ++       files: assets,
     ++       options: options
     ++     },
     ++     process,
     ++   };
     ++ },
      minify: {
        collapseWhitespace: true,
        removeAttributeQuotes: true,
        removeComments: true
      },


   // 文件目录 .electron-vue/webpack.renderer.config.js
plugins: [
    new VueLoaderPlugin(),
    new MiniCssExtractPlugin({filename: 'styles.css'}),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: path.resolve(__dirname, '../src/index.ejs'),
     ++ templateParameters(compilation, assets, options) {
     ++  return {
     ++     compilation: compilation,
     ++     webpack: compilation.getStats().toJson(),
     ++     webpackConfig: compilation.options,
     ++     htmlWebpackPlugin: {
     ++       files: assets,
     ++       options: options
     ++     },
     ++     process,
     ++   };
     ++ },
      minify: {
        collapseWhitespace: true,
        removeAttributeQuotes: true,
        removeComments: true
      },   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

再次运行,就可以了。

上次更新: 10/14/2022, 4:05:31 PM