网上也看了不少把node javascript转换为bytecode的文章,但是实操起来总有些问题,特别是对preload.js部分怎么把preload.js转换为bytecode,说得不那么详尽;我把我自己实践过程详细的描述一下,希望可以帮到有需要的朋友;

1.我是在一个开源项目上简单修改一下,vue3-electron-serialport: vue-cli+vue-cli-plugin-electron-builder+node SerialPort搭建的基于vue3和element-plus串口工具。

Home.vue

/* eslint-disable no-bitwise */
<template><div><el-form><el-form-item>渲染进程</el-form-item></el-form></div>
</template><script>
/* eslint-disable */
import {reactive, ref, onUnmounted, watch, computed, nextTick,
} from 'vue';
import funtest1 from '../funtest1'
const toHexString = bytes =>bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '')+' ';
funtest1('call by Home');
const getForm = () => {    return {};
}export default {name: 'Home',  setup() {return {...getForm(),      };},methods: {}
};
</script>

background.js

import {app, protocol, BrowserWindow, session, ipcMain,
} from 'electron';
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib';
// import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer';
const path = require('path');const isDevelopment = process.env.NODE_ENV !== 'production';app.allowRendererProcessReuse = false;
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } },
]);// 测试 Node API
// const bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// const buf = Buffer.from(bytes);
// console.log('backgroud,buf', buf);async function createWindow() {// Create the browser window.const win = new BrowserWindow({width: 800,height: 600,webPreferences: {contextIsolation: true,preload: path.join(__dirname, '/preload.js'),},});if (process.env.WEBPACK_DEV_SERVER_URL) {// Load the url of the dev server if in development modeawait win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);if (!process.env.IS_TEST) win.webContents.openDevTools();} else {createProtocol('app');// Load the index.html when not in developmentwin.loadURL('app://./index.html');}
}// Quit when all windows are closed.
app.on('window-all-closed', () => {// On macOS it is common for applications and their menu bar// to stay active until the user quits explicitly with Cmd + Qif (process.platform !== 'darwin') {app.quit();}
});app.on('activate', () => {// On macOS it's common to re-create a window in the app when the// dock icon is clicked and there are no other windows open.if (BrowserWindow.getAllWindows().length === 0) createWindow();
});// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {if (isDevelopment && !process.env.IS_TEST) {// Install Vue Devtools// try {//   await installExtension(VUEJS_DEVTOOLS);//   session.defaultSession.loadExtension(//     path.resolve(__dirname, '../../vue-devtools/shells/chrome'), // 这个是刚刚build好的插件目录//   );// } catch (e) {//   console.error('Vue Devtools failed to install:', e.toString());// }// 记得预先安装 npm install vue-devtoolsconst ses = session.fromPartition('persist:name');try {// The path to the extension in 'loadExtension' must be absoluteawait ses.loadExtension(path.resolve('node_modules/vue-devtools/vender'));} catch (e) {console.error('Vue Devtools failed to install:', e.toString());}}createWindow();
});// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {if (process.platform === 'win32') {process.on('message', (data) => {if (data === 'graceful-exit') {app.quit();}});} else {process.on('SIGTERM', () => {app.quit();});}
}

preload.js

const funtest1 = require('./funtest1');
const bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const buf = Buffer.from(bytes);
console.log('preload,buf', buf);
funtest1('call by preload');

funtest1.js

function stringToUint8Array(str){var arr = [];for (var i = 0, j = str.length; i < j; ++i) {arr.push(str.charCodeAt(i));}var tmpUint8Array = new Uint8Array(arr);return tmpUint8Array
}function funtest1(str) {console.log("str",str);const buf = Buffer.from(str);//const buf = stringToUint8Array(str);console.log("buf:",buf);
}module.exports = funtest1;

执行

npm run electron:serve

在console里面看日志,可以发现那个 Buffer.from 返回的对象在preload.js 里面跟在 Home.vue里面返回的对象类型是不一样的,在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库,在普通的Web里面的Javascript环境是调用不了的,

我这个是使用 Electron13.6.2版本,在渲染进程里面能使用Buffer.from,感觉应该跟早期版本渲染进程可以直接调用Nodejs API有关系,虽然新版在渲染进程中不能通过require调用Node API,但是调用Node核心库好像没有问题;我说这个跟下面的内容是有关系的,先做个铺垫;

下面来说说如何使用bytenode;先安装

npm install --save bytenode

修改下package.json,在  scripts 里面增加

"pack": "vue-cli-service electron:build --skipBundle"

在 vue.config.js里面的增加

 electronBuilder: {preload: 'src/preload.js',builderOptions: {...

这样build的时候才会把 preload.js 打包进去;

执行打包

npm run electron:build

在 dist_electron\win-unpacked\resources\app 目录下可以看到,跟   dist_electron\bundled  是一样的

下面的使用bytenode的方法是学习自 https://gitee.com/qjh_2413/vue-electron-bytenode.git

1.在bundled里面把 backgroud.js 重命名为 backgroud.src.js,把 preload.js重命名为 preload.src.js,新建 background.bytenode.js和 preload.bytenode.js

background.bytenode.js

'use strict';const bytenode = require('bytenode');
const fs = require('fs');
const v8 = require('v8');
const path = require('path');v8.setFlagsFromString('--no-lazy');if (!fs.existsSync(path.join(__dirname, './background.jsc'))) {bytenode.compileFile(path.join(__dirname, './background.src.js'),path.join(__dirname,  './background.jsc'));
}require(path.join(__dirname,'./background.jsc'));

preload.bytenode.js

'use strict';const bytenode = require('bytenode');
const fs = require('fs');
const v8 = require('v8');
const path = require('path');v8.setFlagsFromString('--no-lazy');if (!fs.existsSync(path.join(__dirname, './preload.jsc'))) {bytenode.compileFile(path.join(__dirname, './preload.src.js'),path.join(__dirname,  './preload.jsc'));
}require(path.join(__dirname,'./preload.jsc'));

把 background.bytenode.js 复制一份为 backgroud.js,把 preload.bytenode.js复制为 preload.js,

网上有说用 electron .\background.js ,但是经常有人碰到错误,其实就是因为你调用的electron版本跟当前项目的版本不一致;你可以直接使用 .\node_modules\electron\dist\electron.exe .\dist_electron\bundled\background.js   ,用当前项目的electron来执行background.js;

另一种更简单,在 dist_electron\win-unpacked\resources\app 执行跟上面一样的步骤(electronbuilder里面的 asar 先设为 false),然后执行 dist_electron\win-unpacked\(项目).exe,然后把 backgroud.jsc,background.js,preload.jsc,preload.js复制到 bundled 目录里面;

然后执行打包

npm run pack

但是你会发现

preload.js里面调用 Buffer.from 报错,因为 preload.js 生成preload.jsc时是在渲染进程执行的,普通的浏览器javascript环境是调用不了 Buffer.from 这个 Nodejs API的。要解决这个问题,把生成 preload.jsc这个步骤放到 background.js执行,

修改 background.js

'use strict';const bytenode = require('bytenode');
const fs = require('fs');
const v8 = require('v8');
const path = require('path');v8.setFlagsFromString('--no-lazy');if (!fs.existsSync(path.join(__dirname, './background.jsc'))) {bytenode.compileFile(path.join(__dirname, './background.src.js'),path.join(__dirname,  './background.jsc'));
}if (!fs.existsSync(path.join(__dirname, './preload.jsc'))) {bytenode.compileFile(path.join(__dirname, './preload.src.js'),path.join(__dirname,  './preload.jsc'));
}require(path.join(__dirname,'./background.jsc'));

然后在 preload.js里面把生成 preload.jsc 这段代码注释掉,你发现可以正确执行,调用Buffer.from 也不报错了;

我也实验了一下 在 preload.js 里面生成 background.jsc,

修改 preload.js

'use strict';const bytenode = require('bytenode');
const fs = require('fs');
const v8 = require('v8');
const path = require('path');v8.setFlagsFromString('--no-lazy');if (!fs.existsSync(path.join(__dirname, './preload.jsc'))) {bytenode.compileFile(path.join(__dirname, './preload.src.js'),path.join(__dirname,  './preload.jsc'));
}if (!fs.existsSync(path.join(__dirname, './background.jsc'))) {bytenode.compileFile(path.join(__dirname, './background.src.js'),path.join(__dirname,  './background.jsc'));
}require(path.join(__dirname,'./preload.jsc'));

我说下结果吧,如果 background.js 里面不调用 Buffer.from,生成的 background.jsc执行没有报错,background.js里面通过require引用Nodejs API都没有问题,如果我在background.js加上

 const bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];const buf = Buffer.from(bytes);console.log('backgroud,buf', buf);

启动就会报错,

应用启动不起来;

总结:background.js,preload.js这些要转换成bytecode还是在主线程里面执行比较好;

最新更新:把bytenode 编译放入打包流程,请看项目:vue3-electron-bytenode: 把 bytendoe 应用到 electron-builder 构建流程实践;

Electron中使用bytenode保护nodejs代码实践相关推荐

  1. 详解视频中动作识别模型与代码实践

    摘要:本案例将为大家介绍视频动作识别领域的经典模型并进行代码实践. 本文分享自华为云社区<视频动作识别>,作者:HWCloudAI.实验目标 通过本案例的学习: 掌握 C3D 模型训练和模 ...

  2. Electron中使用bytenode加密

    初次学习electron不久,边学习边分享给大家,不对的请指教... 安装bytenode npm install --save bytenode or npm install -g bytenode ...

  3. python pandas 讲解ppt_Python中pandas的分析——包括代码实践,相关,解析,含,实战

    该文章代码均在jupyter Notebook中运行,且已安装re包 # 先读取数据 import pandas as pd f = open(r'C:\Users\qingfeng\Desktop\ ...

  4. 有没有办法从nodejs代码中的package.json获取版本?

    本文翻译自:Is there a way to get version from package.json in nodejs code? Is there a way to get the vers ...

  5. 在Blender中使用代码控制人物模型的头部姿态 - 代码实践mediapipe版本

    在Blender中使用代码控制人物模型的头部姿态 - 代码实践mediapipe版本 flyfish MediaPipe的FaceMesh能够检测468个人脸关键点,这里使用此组件驱动头部动作.本文最 ...

  6. 深度学习中的IOU计算方式和代码实践

    IOU,全称为intersection of union, 中文名"交并比".这个概念理解起来不难,本文将从原理以及代码实践来解读IOU. 首先要说明的是,IOU在检测领域和分割领 ...

  7. ResNet 运行在Cifar10 测试集86.38% Tensorflow 2.1 小白从代码实践中 理解

    环境 tensorflow 2.1 最好用GPU 模型 ResNet 训练数据 Cifar10 或者 Cifar 100 训练集上准确率:92%左右 验证集上准确率:87.6%左右 测试集上准确率:8 ...

  8. 【Electron】酷家乐客户端开发实践分享 — 软件自动更新

    作者:钟离,酷家乐PC客户端负责人 原文地址:webfe.kujiale.com/electron-au- 酷家乐客户端:下载地址 www.kujiale.com/activity/13- 文章背景: ...

  9. 【Electron】酷家乐客户端开发实践分享 — 入坑篇

    作者:钟离,酷家乐PC客户端负责人 原文地址:webfe.kujiale.com/electron-ku- 酷家乐客户端:下载地址 www.kujiale.com/activity/13- 文章背景: ...

最新文章

  1. 2022-2028年中国科学仪器行业研究及前瞻分析报告
  2. 如何调试你的C#程序
  3. 切版网上线,启用qieban.cn
  4. windows下命令行启动tomcat
  5. python 多进程安全日志库 ConcurrentLogHandler 简介
  6. 【caffe-Windows】caffe+VS2013+Windows无GPU快速配置教程
  7. MapReduce编程实践
  8. 【渝粤题库】国家开放大学2021春3907安全原理题目
  9. Django中间件与python日志模块 介绍
  10. 喜用神最正确的算法_各种电磁仿真算法的优缺点和适用范围(FDTD, FEM和MOM等)...
  11. pip安装wxpython报错_Ubuntu 上搭建robotframework
  12. 马化腾:5G和AI双核驱动下,产业互联网的春天来了
  13. Javascript设计模式之单例模式
  14. python教程视频哪个好-Python视频教程谁的好
  15. Java 递归、尾递归、非递归 处理阶乘问题
  16. enetics v1.5.0 绿色版
  17. C#开发之DataGridView填充数据使用小结
  18. kali 切换图形界面_kali切换桌面环境
  19. HTML kind属性怎么用?
  20. Phyton Flask框架学习记录。

热门文章

  1. CentOS 6.8 U盘真机安装图文教程
  2. python猫咪藏在哪个房间_Python 画猫咪
  3. 【亡羊补牢】挑战数据结构与算法 第59期 LeetCode 19. 删除链表的倒数第N个节点(链表)
  4. java迭代器遍历中删除对象
  5. 【超详细】mysql数据库如何卸载干净
  6. Netty——心跳机制与断线重连
  7. 习题10-7 十进制转换二进制(15 分)提问
  8. 疑似天津联通黑产:记一次被流量劫持薅羊毛
  9. Java中两种抛出异常的方式
  10. cmd打包jar包并运行详解