TypeScript 是微软开发的一款 JavaScript 的超集,提供静态语言类型,这样可以让我们的代码更加符合规范,在多人合作开发中非常有用,目前各大 BAT 公司,都有实践 TypeScript 语言,以下简称 ts。

你最好有一些 TypeScript 基础,没有的话,可以看下我录制的免费视频函数式 - 图1,或者开源书籍函数式 - 图2,这只是七八本里面的一本。

安装依赖

可以参考 electron-webpack 文档函数式 - 图3 ,它会告诉你更多的信息。

  1. npm install typescript electron-webpack-ts --dev

electron-webpack-ts 里面其实没有任何代码,只是会帮你安装一些必要的依赖而已。然后初始化 tsconfig.json 配置文件,它规定了你写 ts 的规范,你必须全局安装了 typescript 才会有 tsc 命令,它可以编译 ts 文件。

  1. tsc --init

修改 tsconfig.json 的文件内容,让它继承 electron-webpack 的配置。types 是为了做类型兼容的。

  1. {
  2. "extends": "./node_modules/electron-webpack/tsconfig-base.json",
  3. "compilerOptions": {
  4. "typeRoots": ["./src/main"]
  5. }
  6. }

在介绍里面就有说明 rxjs,它其实是一个非常强大的工具,但是由于学习曲线的陡峭,只有少部分以 Angular 为开发栈的公司在使用它,比如 Daocloud,现在我们先安装它。

  1. npm install rxjs --save

安装 electron-util 的定义文件,这个定义文件跟 API 对应是不全的,所以我们还需要自己魔改一下。

  1. npm install @types/electron-util --save-dev

以插件形式添加类型可以 参考这里函数式 - 图4 , 新建 src/main/shim.d.ts 文件

  1. import util from 'electron-util'
  2. declare module 'electron-util' {
  3. export function loadFile(win?: any, path?: string): void
  4. }

主进程入口

  • 导入依赖
  1. import { app, BrowserWindow } from 'electron'
  2. import util from 'electron-util'
  3. import { fromEvent } from 'rxjs'

fromEvent函数式 - 图5rxjs 的创建函数,以下两种方式等价,它会自动监听你的事件,通过 subscribe 来传递处理回调,类似于 Promisethen

  1. fromEvent(<any>win.webContents, 'devtools-opened').subscribe(() => {
  2. win.focus()
  3. setImmediate(() => win.focus())
  4. })
  5. win.webContents.on('devtools-opened', () => {
  6. win.focus()
  7. setImmediate(() => win.focus())
  8. })
  • 窗口创建函数

内容基本跟之前的一致,只不过加了 TypeScript 类型,完整代码可以参考源码仓库。

  1. let mainWindow: BrowserWindow | null
  2. function createMainWindow(opts?: Electron.BrowserWindowConstructorOptions) {
  3. const win = new BrowserWindow(opts)
  4. if (util.is.development) {
  5. win.webContents.openDevTools()
  6. win.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`)
  7. } else {
  8. util.loadFile(win, 'index.html')
  9. }
  10. fromEvent(<any>win, 'close').subscribe(() => (mainWindow = null)) // 关闭事件
  11. fromEvent(<any>win.webContents, 'devtools-opened').subscribe(() => {
  12. // 打开开发者工具栏后
  13. win.focus()
  14. setImmediate(() => win.focus())
  15. })
  16. return win
  17. }
  • 事件处理函数

一个一个的写,不如写一个循环来帮我们做事件绑定。

  1. function ready(): void {
  2. mainWindow = createMainWindow()
  3. }
  4. function windowAllClosed(): void {
  5. if (util.is.macos) {
  6. app.quit()
  7. }
  8. }
  9. function activate(): void {
  10. if (!mainWindow) {
  11. mainWindow = createMainWindow()
  12. }
  13. }
  14. const AppEventMap: any = {
  15. ready,
  16. 'window-all-closed': windowAllClosed,
  17. activate
  18. }
  19. Object.keys(AppEventMap).map(eventName =>
  20. fromEvent(<any>app, eventName).subscribe(AppEventMap[eventName])
  21. )

通过一个 map 的映射,来自动监听事件。