Electron+serialport串口开发
前端开发利用Electron + node-serialpost实现串口通信,最近有需求尽可能直接读取地磅数据,现有项目是vue写的网页项目,为了最大化的减少工作量,调研后发现用electron+serialport满足需求,通过iframe加载已经写好的页面,再通过与iframe通信传输串口数据即可。但折腾来折腾去,踩了各种坑也花了接近两周的时间,刚好遇到疫情,就研究了一波,特此记录一下配置过程,主要是整合资源,将全过程记录。
安装 electron serialport electron-rebuild
安装electron受网络环境影响可能需要科学上网,不能科学上网就用cnpm。
mkdir my-electron-app && cd my-electron-app\ npm init 复制代码
cnpm i electron --save-dev cnpm i serialport cnpm i electron-rebuild --save-dev 复制代码
安装依赖
node-serialport是一个让node可以访问电脑串口设备的原生模块,需要编译,也是出问题最多的一个环节。编译需要做一些准备工作。
安装node-gyp、VS2017和python
npm install -g node-gyp npm install --global --production windows-build-tools npm config set python python2.7 npm config set msvs_version 2017 复制代码
编译
.\node_modules\.bin\electron-rebuild.cmd 复制代码
可能出现的问题
安装windows-build-tools时卡顿,此时一大神发现了解决方案,我按照此步骤,成功解决问题。
NODE_MOUDLE_VERSION不一致,这个错误有可能在软件运行时抛出。
其他各种问题,只能百度,实在不行就google,多次尝试,我花了一周多的时间才搞好...
成功一次就别在瞎折腾了,放过在下也放过自己,我重新搞了一次,结果又遇到各种问题...
测试serialport
若当前无硬件设备,需要下载虚拟串口工具(VSPD虚拟串口)和串口调试工具。
package.json中将入口文件设置为main.js
// package.json ... "main": "main.js" ... 复制代码
添加main.js和html文件
在main.js添加测试代码,若控制台输出端口信息,则证明已经成功了95.8%了。
const serialport = require("serialport"); serialport.list().then((ports) => { console.log(ports); }); 复制代码
在html中使用serialport
上一步成功后,我们尝试将serialport用在html页面中,发现控制台会报错,经过查找各种资料,发现Electron 9.0开始,官方推荐在渲染进程中不使用原生nodejs模块,哦吼,所以我们该怎么办。
想到我们在main.js主线程上能用,那我们可以研究研究主线程和渲染线程的通信。Electron提供了ipcMain和ipcRenderer API,网上文章页讲的很详细,找了一份带有示例的与大家分享:Electron笔记之进程间通信(ipc)
html页面设置串口参数:串口名称、波特率、校验位和停止位等参数,设置完将参数发送至主线程。
主线程接收参数,打开串口,接收数据(利用串口调试工具发送数据)。
npm start启动项目,发现得到数据,成功!
const { ipcMain } = require("electron"); ipcMain.on("open-serialport", (event, args) => { const port = new serialport(path, options, errorCallback); port.on('data', data => { // 将串口接收的数据返回渲染进程,用于显示 event.sender.send("send-data", `${data}`); }); }); 复制代码
vscode对electron主线程调试
程序员怎么能不会调试呢!参照此篇文章进行调试。
打包
上面的都行的通之后,通过与iframe的通信便满足需求了。接下来研究怎么打包成安装包,因为还涉及到客户端的更新升级,在下用的electron-builder,安装完之后,在package.json添加打包命令,执行命令 npm run build 发现大量报错,一看都是网络原因,怎么办,不要怕,大神多的很,请参照electron-builder打包采坑问题汇总配置,一个字:好使!打包完后dist文件夹长这样,exe就是我们的安装程序了。
npm i electron-builder 复制代码
// package.json "build": { "appId": "com.xxx.app", "productName": "marco-test-app", "publish": [ { "provider": "generic", "url": "http://localhost:7777/download", "channel": "latest" } ], "mac": { "target": [ "dmg", "zip" ] }, "win": { "target": [ "nsis", "zip" ] }, "nsis": { "oneClick": false, "allowToChangeInstallationDirectory": true, "allowElevation": true, "createDesktopShortcut": true, "createStartMenuShortcut": true, "shortcutName": "marco-app" } }, "scripts": { "start": "electron --inspect=8888 .", "build": "electron-builder --win --x64" }, 复制代码
自动更新 electron-updater
给了用户安装包,那必须得支持版本更新啊,我们怎么搞?
不要怕,electron也提供了更新策略,安装electron-updater,然后在main.js中检测更新,在package.json -> build -> publish中配置更新地址,为方便本地测试,我们用node在本地配置更新地址,可参考Electron应用实现自动更新 配置本地环境,打包的更新文件一定要放对位置,一定要有latest.yml文件,若不存在,需要在package.json -> build -> publish添加 "channel":"latest",配置完,安装软件后,如有高版本就会自动下载安装。
本地运行npm start测试更新时,可能会报错:dev-app-update.yml文件不存在或者Update for version X.X.X is not available (latest version: x.x.x, downgrade is disallowed),测试在本地建立此文件,将打包的文件夹win-unpacked\resources中app-update.yml内容复制过来即可,更多错误参考electron-updater更新electron应用程序。
npm i electron-updater 复制代码
// main.js app.whenReady().then(() => { createWindow(); checkForUpdates(); }); function checkForUpdates() { // 更新地址,即新版本存放地址 autoUpdater.setFeedURL("http://localhost:7777/download"); autoUpdater.checkForUpdates(); autoUpdater.on("update-available", function (info) { dialog.showMessageBox({title: '更新', message: '有更新可用'}); }); autoUpdater.on('update-not-available', function (info) { dialog.showMessageBox({title: '无更新', message: '无更新可用'}); }) autoUpdater.on("update-downloaded", (info) => { dialog.showMessageBox( { // icon: __static + "/favicon.png", type: "info", title: "软件更新", message: `已更新到最新版本(${info.version})请重启应用。`, // detail: detail, buttons: ["确定"], }, (idx) => { // 点击确定的时候执行更新 if (idx === 0) { autoUpdater.quitAndInstall(); } } ); }); } 复制代码
"build": { "appId": "com.xxx.app", "productName": "marco-test-app", "publish": [ { "provider": "generic", "url": "http://localhost:7777/download", "channel": "latest" } ], "mac": { "target": [ "dmg", "zip" ] }, "win": { "target": [ "nsis", "zip" ] }, "nsis": { "oneClick": false, "allowToChangeInstallationDirectory": true, "allowElevation": true, "createDesktopShortcut": true, "createStartMenuShortcut": true, "shortcutName": "marco-app" } } 复制代码
总结
这一套流程下来,都要哭了,会遇到各种各样的问题,我一共花了接近两周时间(一天不到两小时)才搞好,太难了,中途想过放弃不搞了,但他越出错我越想搞,幸运的是最终成功了,不能保证按照这个流程一定成功,仅记录过程。
作者:MarcoMa
链接:https://juejin.cn/post/7029236252557705252