Electron.js 30中使用Tabulator

最近在忙一个新的项目,因为项目工期要求很短、并且我对这个项目十分不想投入过多的精力,所以选择使用Electron.JS框架进行开发。 但是Electron默认是不支持ESM语法的,这就使得如果想在项目中引入Tabulator等依赖项目时,会遇到语法不兼容问题。 一、网上看到的介绍是错误的: 与网上说的在package.json中增加type: module不同,不需要在package.json中增加type声明。因为package.json中增加声明,似乎是告知electron框架,主进程使用ESM语法。但是实际上主进程、也就是main.js文件仍然是CommonJS语法的,无需支持ESM语法。 二、实际只需要在渲染层引入ESM语法的支持: 也就是在需要的html文件中,将引入script文件的地方进行调整,从: <script src=”a.js”></script> 改成: <script type=”module” src=”a.mjs”></script> 这样渲染层的js解析器、也就是chromium浏览器的V8引擎就知道引入的js脚本是支持ESM的,并且启用ESM语法支持了。 三、在a.mjs文件中: 此时在a.mjs文件中,不必再使用require引入包,可以使用import引入包了。 但是因为Tabulator并没有默认的default导出入口(我也不知道具体应该怎么更准确的描述)、同时不清楚为什么不能直接按照包名直接导入(虽然我也是NPM安装的),所以导入包的具体语句如下: import {TabulatorFull as Tabulator} from ‘./node_modules/tabulator-tables/dist/js/tabulator_esm.min.js’; 剩下的具体使用就和其他正常使用没有差别了。 四、打包: 比较担心这样“自己胡乱导入”的包,最终打包生成可执行资源包的时候是否会出问题,经过实际npm run…

Electron开发备忘

接了一个甲方的开发任务,经过选型考虑(其实是完全没有考虑),决定使用Electron进行开发。为什么要用Electron进行这次项目的开发呢?我对这个脚手架以及nodejs语言,几乎可以说是没有任何经验的。 主要考虑如下: 1、我想最终交付给用户的时候,是一个本地客户端的产品形式; 2、通过html快速实现页面、美观的页面; 3、这个产品本身就是一个BS架构的,那么在客户端这边,能够通过浏览器实现是最好的选择; 4、本来可以完全做成基于浏览器的形式,但是那会导致历史上经常遇到的问题:我无法控制用户的浏览器,尤其是一些“领导”们使用的浏览器,往往都是很陈旧的,页面表现会不一致。 暂且处于如上考虑,今天使用Electron搭建了一个基本开发环境,并且做了一些粗糙的页面,响应了页面上的事件,引入BootStrap5对页面进行美化,尝试了将项目make成exe运行包。感觉一切都可以接受。 另:当前开发环境在软件运行时,可以从login页面的底部看到。 一、项目存放路径: ~/Desktop/electron-app/my-electron-app 二、启动项目命令: npm run start 三、打包项目命令: npm run make 四、打包时为什么没有将bootstrap5的样式打入运行时的包中? 运行提示:filed to load resource net err_file not found…

小工具开发备忘

最近用C++语言写一个小的工具程序,进展还算顺利,大的方向和功能开展的比较顺利,但是细节上有很多小问题。为了确保软件开发的进度,我是抓大放小,先力求能将整体功能全部实现出来。 对于细节问题,只能是做些备注、放在一旁,等软件整体完成之后,再回过头来逐一推敲了。这里记录一下遇到的小问题,当是给自己的备忘,等以后有时间了,再慢慢研究。 1、《系统托盘菜单点击之后500毫秒内的残影》 这个问题并不严重,临时解决方案是在程序中触发截屏时,先延迟一段时间再开始进行截屏。 2、《std::vector.size()返回的是size_t类型》 这并不是“放在一旁、暂且不管”的缺陷,而是我在写代码的时候遇到的一个“引起程序崩溃”的bug。实际上并非真的导致了程序的崩溃,而是因为wxWidgets中的调试断言弹出了警告对话框。 只不过因为我对C++不熟悉、又这个弹出警告框的文字实在难于阅读,所以起初一直以为是程序崩溃了。找了好久才找到原因,并且发现只不过是在f(x)函数的调用是,参数x使用了int类型,而真正应该使用的是size_t类型。虽然int和size_t几乎一样,但严格的断言判定最终生成了警告信息。 这个问题虽然已经解决,但是额外的需要再补充一下细节知识的缺失——《C++中的int和size_t有什么不同?》 3、《wxWidgets似乎没有事件广播机制》 我现在对wxWidgets的认知来看,它是没有事件广播机制的,但是对于我现在正在开发的一个“相对复杂”的窗口,如果能够以事件广播,将会令代码更加简单。所以想到了一个也许笨拙的方法——使用全局单例——来临时解决问题。 ================ 以下为尚未这里问题 ================ 一、已解决的问题主要有: 1、为什么在程序退出时会产生一些内存泄漏? 答:之前使用的退出方式不正确,之前的退出方式在“程序退出”时,虽然也调用了析构函数,但是那个调用析构函数的时候,实际上内存已经泄露了。我在那个析构函数中进行资源释放,实际上是对已经泄露了内存、且资源句柄已经无效的时刻,才去释放资源,结果就是无权访问会引发程序崩溃。 按照之前的错误思路,怎么办呢?释放就会崩溃,所以只能选择不释放资源,这样程序就不会崩溃了。但是在debug调试器中,就会看到有内存泄漏产生。虽然这里产生的内存泄漏会再被系统回收处理,但是这相当于是将“烂摊子”交给了操作系统的内存控制器。 现在已经解决了。解决的方法就是改用正确的退出函数,这样正确的退出函数会触发正确的析构过程,在这个新的析构过程中,释放资源,此时的资源还没有泄露,也就可以正常的被释放掉。 2、icontray的弹出菜单文字的动态调整 这里只是一个小技巧而已:将mainFrame的指针传给iconTray,这样iconTray内部就能在弹出菜单之前,判断出mainFrame当前的状态,再根据mainFrame的当前状态实时生成菜单,就能够令弹出菜单的内容“实时”,使用体验会比较好。 二、尚未解决的问题: 1、程序多次被启动,虽然我用互斥锁能判断出来,但是第二次启动只能弹出一个提示“已有实例,不要重复启动”。 但是我想做的更好一些,使用IPC通信,第二次的启动可以通过IPC通知第一个实例,第一个实例如果正处于隐藏状态(icontray状态),就自己重新唤醒起来。 2、paintDC的绘制效率很低:已经使用双缓存和悬浮层两个方案,共同解决了这个问题。 3、wxSashLayoutWindow窗口的拖拽改变尺寸,产生的事件 OnSashDrag(wxSashEvent&) 这个事件折磨了我大约4个小时,后来才想起来打印看一下,结果发现这是在鼠标抬起的时候才唯一的产生一次响应。难怪无法实时改变窗口的大小。还没有解决思路。