Files
electronTs-ks-demo/README.md
2024-09-27 01:23:51 +08:00

11 KiB
Raw Permalink Blame History

electronTs

这个项目大致作用就是:前端有 electron-vue那熟悉 nodejstypescript 的同学也是时候该有个能开箱即用的electron框架了项目正在开发完善中请保持每天多次拉取代码的习惯

需要一说的是这个项目开发了大量的装饰器做到了代码的编写风格优雅化和定制化同时也更加类似java的springboot框架更采用了约定大于配置的原则所以也要求阅读代码的同学对ts的掌握度稍微高点同时更加详细的使用文档还没时间写下面的文档将就看看主要还是推荐看代码代码里面基本有详细的注释

忘记说了本项目基于nodejstypescriptelectronjadegulp.jslesstypescript 装饰器等实现!!

1项目结构说明

这边重点介绍src/目录,因为src/才是我们项目开发的源码目录!而dist/目录是项目上线后使用的。所以不关心!!

|-src
|____core    核心TS逻辑的源码
| |____types 一些自动以的类型声明
| |____net   网络请求的封装
| |____config 项目的整体配置文件
| |____annotation 存放自定义装饰器
| |____utils   项目的工具函数
| |____controller 项目的控制器,主要在这里控制页面的显示,记住每个桌面端页面都是一个控制器!
| |____model    Typescript的存取器这里主要存放当前启动主窗口的实例
| |____interactive  各种系统界面的ui例如菜单弹窗进度条图标等
| |____ipc    渲染进程和主进程的ipc监听
| | |____application.ipc.ts  程序系统核心级别的ipc监听
| | |____components.ipc.ts   具体到默写页面级别的ipc监听
| |____run   程序真正的入口启动类
|____App.ts  程序的开始类,主要初始化 run
|____application  应用程序页面
| |____page    每个controller都对应这里的一个页面
| |____layout  页面的公共布局
| |____components 存放页面的公共复用组件
| |____assets   静态资源
| | |____less   css样式
| | |____js     
| | | |____page 这里存放对应page页面的js
| | | |____lib  存放js公共库例如jquery等
| | |____img    存放图片

2源码分析

2.1:核心装饰器间调用思路

  • 第一步:Init.run.ts@AutoLoadWindow() 装饰器首先被运行,然后会自动加载启动类Home.controller.ts

  • 第二步:这一步首先运行类属性上的装饰器@Inject()@Inject()会去实例化被装饰属性的类型,赋值给被装饰的属性!

  • 第三步:@Inject()运行完后,会紧接着运行类的方法上的装饰器,先后顺序为:@Render()@Ipc(),但是实际运行的效果却是 @Ipc()@Render()之前,主要原因是@Render()中有await导致的,这其中@Render()是最核心的装饰器之一。主要作用是:获取方法传给模板的数据,根据jade模板&数据生成html页面,载入html然后创建窗口!

  • 第四步:前面三步走完后,用户已经可以看到窗口了,而@Ipc()装饰器的主要作用在于自动调用传入类中的所有方法实现ipc监听。

注意:当然上面的步骤只是核心装饰器的运行流程,还有很多其他装饰器也是同步执行的,这里没详细介绍!可以阅读源码~~

2.2:渲染进程创建窗口思路

  • 1Init.run.ts类上有个装饰器@CreateApplicationIpc(),该装饰器也继承Run类,之后内部实例化ApplicationIpc()类,这其中会通过 ipcMain.on去监听前端的事件openWindow
  • 2创建窗口分为三种情况
    • 1独立窗口
    • 2依附在主窗口上的父子窗口
    • 3依附在非主窗口上的父子窗口
  • 3前端js通过使用:ipcRenderer.sendSync('openWindow', ['Home.controller/Setting', true]) 发起通知,让主进程创建窗口!这其中参数:Home.controller/Setting,表示调用Home.controller.ts里面的Setting方法创建窗口!

2.3:已提供的装饰器

  • @AutoLoadWindow()

    • 作用根据配置文件自动引入主controller文件
    • 使用:仅限启动类Run
    • 参数:无
    • 注意:无
  • @Render(templateName?:string)

    • 作用:根据配置文件自动创建窗口
    • 使用:用在controller/ 文件夹下的控制器类方法中
    • 参数templateName要渲染的模板名称选填
      • 未填写参数:自动使用被装饰的方法名去寻找路径src/application/page/**/*.jade路径下的模块文件,并自动读取Index.config.ts对应的PageSizePagePath
      • 已填写参数:同上,只不过使用传入的名称去寻找模板和配置文件等信息
    • 注意:被装饰的方法的名字需要和模板名称,配置文件中PageSizePagePath都相同!!!
  • @Ipc(IpcParams: { new (...args: any[]): {}; }[])

    • 作用:自动注册窗口相关的局部 IPC
    • 使用:用在controller/ 文件夹下的控制器类方法中
    • 参数IpcParams需要被注册的未实例化的类数组
    • 注意:参数必须填写未实例化的类,构成数组,例如:@Ipc([ Application, TestIpc ])
  • @CreateIpc(IpcParams: { new (...args: any[]): {}; }[])

    • 作用:自动注册程序公共的全局 IPC
    • 使用仅限启动类Run
    • 参数IpcParams需要被注册的未实例化的类数组
    • 注意:参数必须填写未实例化的类,构成数组,例如:@CreateApplicationIpc([ Application, TestIpc ])
  • @Injectable()

    • 作用:依赖收集,主要用来存储被装饰的类到存取器
    • 使用:用在类上
    • 参数:无
    • 注意:和 @Inject() 搭配使用
  • @Inject()

    • 作用:依赖注入,将@Injectable()中存的类取出并实例化到类属性上
    • 使用:用在类的属性上
    • 参数:无
    • 注意:和 @Injectable() 搭配使用
  • @GET(RequestParams?: { url?: string, useHandle?: boolean })

    • 作用:发送GET请求
    • 使用:用在service层类的方法上
    • 参数:
      • url如果不传参数将自动依据方法名作为对象的key去寻找Config.ApiUrl.ApiList[方法名]的接口地址,如果传参数,使用传入的参数作为接口请求地址
      • useHandle如果接口返回的数据需要做特殊处理那么可以设置 useHandletrue,中间被@GET注解的方法将会获得ajax请求的结果如果为flase方法将不会获得任何参数!
    • 注意:不填写参数时,请保持方法名和 Config.ApiUrl.ApiList[key]中的key名称一致
  • 【设计中..】@POST(RequestParams?: string)

    • 作用:暂无描述
    • 使用:暂无描述
    • 参数:暂无描述
    • 注意:暂无描述
  • 【设计中..】@DELETE(RequestParams?: string)

    • 作用:暂无描述
    • 使用:暂无描述
    • 参数:暂无描述
    • 注意:暂无描述
  • 【设计中..】@PUT(RequestParams?: string)

    • 作用:暂无描述
    • 使用:暂无描述
    • 参数:暂无描述
    • 注意:暂无描述
  • @CreateApplicationMenu()

    • 作用:创建程序的顶部菜单!
    • 使用:仅限启动类Run
    • 参数:无
    • 注意:无
  • @CreateTouchbar()

    • 作用:创建MacOs系统上的Touchbar
    • 使用:仅限启动类Run
    • 参数:无
    • 注意:仅限MacOs系统有效,如果是windows可删除该装饰器
  • @CreateTray()

    • 作用:创建MacOs系统上顶部全局菜单的图标!
    • 使用:仅限启动类Run
    • 参数:无
    • 注意:仅限MacOs系统有效,如果是windows可删除该装饰器

更多的请自行阅读源码!!

3注意事项

3.1 解决下载electron缓慢的问题

在项目初始的时候npm inode会去下载electron,因为被墙的原因你可能需要四五个小时都不一定能把electron依赖下载完成。所以请自行参考这篇文章手动修改,跳过程序的node install.js的过程,加快速度!!

教程地址:假装这里有链接


PS如果上面的方案不能解决你的问题亲测无效那么请先删除项目的node_modules依赖,然后重新 npm i,当看到终端在下载electron的时候,请强制停止终端。然后从这个地址:

https://npm.taobao.org/mirrors/electron/

下载对应你系统的electron包。

MacOs系统

我这边下载的是Macos系统的9.1.0最新版electron,文件名:electron-v9.1.0-darwin-x64.zip

下载完成后解压压缩包,然后将文件夹中的Electron.app复制到应用程序中,然后修改package.json中的命令el/Applications/Electron.app/Contents/MacOS/Electron . 即可!!

示例配置文件为:

  "scripts": {
    "el": "/Applications/Electron.app/Contents/MacOS/Electron ."
  }

Windows系统

如果你是Windows系统,那么你可以下载 electron-v9.1.0-win32-x64.zip 的包!也是解压然后将解压后的文件移动到没有中文名和空格的路径中,然后使用electron.exe去运行项目即可!

示例配置文件为:

  "scripts": {
    "el": "C:\\electron-v9.1.0-win32-x64\\electron.exe ."
  }

3.2 修改jade插件

因为 jade 插件支持的参数 globals 只支持数组!所在再把config/Index.config.ts中的jadeCompile0ptions传给模板application/layout/index.jade的时候不好分开遍历cssjs

所以需要修改globals的数组为对象:

  • 修改后的效果如下:
// jade 模板引擎配置,更多参数自行阅读声明文件
public static jadeCompile0ptions: JadeOptions = {
    pretty: true, // 编译输出后是否保留源码格式true 保持
    globals: {
        css: [
            'http://mdui-aliyun.cdn.w3cbus.com/source/dist/css/mdui.min.css',
            'http://at.alicdn.com/t/font_1934749_6mfzbfby21d.css',
        ],
        js: [
            'https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js',
            'http://mdui-aliyun.cdn.w3cbus.com/source/dist/js/mdui.min.js'
        ]
    }
}

修改步骤

1打开文件node_modules/@types/jade/index.d.ts,找到接口JadeOptions,修改原先的globals为下面类型:

...
globals?: {
    css: string[],
    js: string[]
};
...

2打开文件node_modules/jade/lib/index.js,找到第133行 ~ 141行,注释这些代码即可。实例如下:

...
 var globals = [];

// 下面这些注释掉
// if (options.globals) {
//   globals = options.globals.slice();
// }

// globals.push('jade');
// globals.push('jade_mixins');
// globals.push('jade_interp');
// globals.push('jade_debug');
// globals.push('buf');
// 上面这些注释掉

  var body = ''
...

重新运行项目即可!!