nodeAPi和Electron内置模块的杂烩(八)

1,649 阅读7分钟

微信公众号:[猫十二的日常],欢迎留言和指出问题,深漂中的前端团子,猫十二的铲屎官,生活不止code,还有猫和你。

简介

在electron中,我们可以使用所有NodeJs的内置模块,包括第三方的npm包,它还提供为开发原生桌面应用提供了一个额外的内置模块,有些模块只能在主进程中使用,有些模块只能在渲染进程(web页面)使用,有些则是在两个进程都可以使用。

基本规则:只要这个模块涉及到GUI或者底层的相关的,就只能在主进程中使用,前面的有文章介绍主进程和渲染进程的概念

现在我们将对官网提供的api进行一一的尝试和学习

进程 process

  • 适用范围:Main、Renderer
  • 作用:用于处理对象的扩展

Electron的process对象继承了Node的process,还新增了以下的事件、属性和方法,,但是在沙盒化的渲染进程中,process对象包含的只是API的子集

事件 'loaded'

当Electron加载了它的内部初始化脚本并且是正要开始加载网页或主脚本时触发。当我们不在渲染进程集成node时,我们也可以通过这个方法像全局注入一些node的方法(我全部代码放在一块了,不懂看我的github,一月18号那个)aymfx的github

//main.js
const { app, BrowserWindow, ipcMain } = require("electron");
const path = require("path");
app.whenReady().then(() => {
  let win = new BrowserWindow({
    width: 1920,
    height: 1080,
    webPreferences: {
      preload: path.resolve(__dirname, "./preload.js"), //preload String (可选) -在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成Node, 此脚本都可以访问所有Node API 脚本路径为文件的绝对路径。 当 node integration 关闭时, 预加载的脚本将从全局范围重新引入node的全局引用标志
      // nodeIntegration: true,
      devTools: true,
      contextIsolation: false,
      enableRemoteModule: true, //启用remote
      webviewTag: true, //需要设置webview来启用这个
    },
  });
  const contents = win.webContents;
  contents.openDevTools(); //打开调试工具
  win.loadFile("index.html");
});
//preload.js
const _setImmediate = setImmediate;
const _clearImmediate = clearImmediate;
process.once("loaded", () => {
  window.setImmediate = _setImmediate;
  window.clearImmediate = _clearImmediate;
  console.log(global, "加载完");
});
console.log(global, "加载完");

// renderer.js
console.log(window.setImmediate);
console.log("开始");
setImmediate(() => {
  console.log("结束");
});
console.log("中间");

结果

image-20210118113715633

我们需要在创建win窗口的时候那个地方注入preload.js,这块好像不能用相对的路径不然会加载不出来

preload: path.resolve(__dirname, "./preload.js")

通过这个我们可以注入一些node方法在网页上,供我们调用了

属性

  • console.log("show:", process.defaultApp);

只读布尔值=>作为一个默认的App被启动时,在主进程打印的是true在渲染进程打印的是undefined

  • console.log("show:", process.isMainFrame);

只读布尔值=>当渲染器的上下文是主渲染进程时,如果需要当前框架的id,则需要使用webFrame.routingId

  • console.log("show:", process.mas);

只读布尔值=>要用 Mac Apple Store构建,这属性就是true,否则就是false

  • console.log("show:", process.noAsar);

将其设置为true将禁用对Node内置模块中的asar存档的支持

  • console.log("show:", process.noDeprecation);

用于控制弃用警告是否被打印到stder。将其设置true将会禁用弃用警告。 使用此属性代替 -no-deprecation 命令行标志。

  • console.log("show:", process.resourcesPath);

只读布尔值=>返回当前的资源路径

  • console.log("show:", process.sandboxed);

只读布尔值=> 在渲染进程中是true,其他为false

  • console.log("show:", process.throwDeprecation);

用于控制是否将弃用警告当做例外。 设置它为true 时会抛出错误。 使用此属性代替 --throw-deprecation 命令行标志。

  • console.log("show:", process.traceDeprecation);

用于控制打印到 stderr 的弃用中是否包含其堆栈跟踪。 将此设置为 true 将会打印对弃用的堆栈跟踪。 此属性代替 --trace-deprecation 命令行标志。

  • console.log("show:", process.traceProcessWarnings);

一个 Boolean, 用于控制是否将进程的警告打印到包含堆栈跟踪的 stderr中 。 将此设置为 true 将打印对进程警告的堆栈跟踪(包括弃用)。 此属性代替 --trace-warnings 命令行标志。

  • console.log("show:", process.type); 只读string 类型
    • browser 主进程
    • renderer 渲染进程
    • worker web woreker
  • console.log("show:", process.versions.chrome);

只读布尔值=>string,一个表示 Chrome 版本的字符串。

  • console.log("show:", process.versions.electron);

只读布尔值=>string,一个表示 Electron 版本的字符串。

  • console.log("show:", process.windowsStore);

只读布尔值=> 是否运行在window Store app上面

main.js打印出来的

show: true
show: undefined
show: undefined
show: undefined
show: undefined
show: /Users/aymfx/gitRepository/electron-examples/2020-01-18/node_modules/_electron@11.2.0@electron/dist/Electron.app/Contents/Resources
show: undefined
show: undefined
show: undefined
show: undefined
show: browser
show: 87.0.4280.141
show: 11.2.0
show:

renderer.js打印出来的

renderer.js:8 show: undefined
renderer.js:9 show: true
renderer.js:10 show: undefined
renderer.js:11 show: undefined
renderer.js:12 show: undefined
renderer.js:13 show: /Users/aymfx/gitRepository/electron-examples/2020-01-18/node_modules/_electron@11.2.0@electron/dist/Electron.app/Contents/Resources
renderer.js:13
renderer.js:15 show: undefined
renderer.js:16 show: undefined
renderer.js:17 show: undefined
renderer.js:18 show: undefined
renderer.js:19 show: renderer
renderer.js:20 show: 87.0.4280.141
renderer.js:21 show: 11.2.0
renderer.js:21 show: undefined

方法

process.crash()

导致当前进程崩溃的主线程。直接搞垮应用

![image-20210120115212278](/Users/liuyang/Library/Application Support/typora-user-images/image-20210120115212278.png)

process.getCreationTime()

返回 Number | null -从纪元开始的毫秒数,如果信息不可用则返回null

表示应用的创建时间,如果无法获取创建时间流则返回null

  console.log(process.getCreationTime()); //1611114906194.985

process.getIOCounters()

这个额返回io数量,仅限win和linux平台

process.getHeapStatistics()

返回v8的堆数据

  console.log(process.getHeapStatistics());
  /**
     {
      totalHeapSize: 4488,
      totalHeapSizeExecutable: 608,
      totalPhysicalSize: 3849,
      totalAvailableSize: 4190654,
      usedHeapSize: 3104,
      heapSizeLimit: 4194048,
      mallocedMemory: 128,
      peakMallocedMemory: 711,
      doesZapGarbage: false
    }
   */

process.getBlinkMemoryInfo()

返回带有闪烁内存信息的对象。这对于调试与渲染/ DOM相关的内存问题可能很有用。请注意,所有值均以千字节为单位报告

  console.log(process.getBlinkMemoryInfo() ); //{ allocated: 0, total: 0 }

process.getProcessMemoryInfo()

返回一个对象,该对象提供有关当前进程的内存使用情况统计信息,Chromium不提供macOS的residentSet值。这是因为macOS对最近未使用的页面执行内存压缩,私有内存更能代表macOS上进程实际的压缩前内存使用情况。

  process.getProcessMemoryInfo().then((res) => {
    console.log(res); //{ private: 62572, shared: 32 }
  });

process.getSystemMemoryInfo()

返回 Object:

  • total Integer - 系统可用的物理内存总量(Kb)。
  • free Integer - 应用程序或磁盘缓存未使用的内存总量。
  • swapTotal Integer Windows Linux - 系统交换内存容量(单位:千字节)。
  • swapFree Integer Windows Linux - 系统可用交换内存大小(单位:千字节)。
 console.log(process.getSystemMemoryInfo()); //{ total: 16777216, free: 14788 }

process.getSystemVersion()

  console.log(process.getSystemVersion()); //11.1.0

process.takeHeapSnapshot(pathName)

返回一个布尔值表示是否成功创建了一个快照,会生成一个文件快照

console.log(process.takeHeapSnapshot("index.js")); //true

image-20210120152701009

process.hang()

导致当前进程挂起的主线程。

  console.log(process.hang()); // 挂起 不显示 页面不显示了

process.setFdLimit(maxDescriptors)

  • maxDescriptors Integer

将文件描述符的软限制设置为 maxDescriptors 或 OS 硬限制, 其中以当前进程较低的值为准。

支持命令行开关

Electron支持的命令行开关,您可以在app 模块的ready事件生效之前,使用app.commandLine.appendSwitch将它们附加到您的应用程序的主要脚本中

--auth-server-whitelist=url

启用了集成身份验证的以逗号分隔的服务器列表。

image-20210120173205289

对于一些nodejs的命令也可以加到后面去

具体的文档 支持命令行开关

环境变量

Electrond的某些行为受环境变量的控制, 因为它们比命令行标志和应用程序的代码更早初始化,可以在不改变代码的情况下控制应用程序的行为

posix shell 示例

export ELECTRON_ENABLE_LOGGING=true

win控制台

set ELECTRON_ENABLE_LOGGING=true

具体的文档 环境变量

File 对象

在文件系统中,使用html5的File进行操作文件,并且Electron已经向文件接口添加了一个path属性,在文件系统暴露了一个真实的路径

Index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Electron演示</title>
</head>

<body>
    Electron演示
    <div id="holder">
        Drag your file here
        <img src="" class="img" />
    </div>
    <script src="./renderer.js"></script>
</body>
</html>

renderer.js

document.addEventListener("drop", (e) => {
  e.preventDefault();
  e.stopPropagation();

  for (const f of e.dataTransfer.files) {
    let img = document.querySelector(".img");
    console.log("File(s) you dragged here: ", f.path);
    img.src = f.path;
  }
});
document.addEventListener("dragover", (e) => {
  e.preventDefault();
  e.stopPropagation();
});

最后拖拉照片的效果

image-20210120180103723

如果觉得我的文章还可以,点个赞或者关注一下下,还有精彩的故事等着你哦,还可以云撸猫