import EventEmitter from 'events' ; import type { BrowserWindowConstructorOptions } from 'electron' ; import { app , BrowserWindow , protocol } from 'electron' ; import { dev } from 'electron-is' ; import createProtocol from 'umi-plugin-electron-builder/lib/createProtocol' ; import type { App } from '@/core/App' ; import type { MainEvents } from '@/common/Events' ; protocol . registerSchemesAsPrivileged ( [ { scheme : 'app' , privileges : { secure : true , standard : true } } , ] ) ; export interface BrowserWindowOpts extends BrowserWindowConstructorOptions { /**
     * URL
     */ identifier : Main . WindowName ; title ? : string ; width ? : number ; height ? : number ; devTools ? : boolean ; /**
     * 允许 renderer 进行使用 remote 模块
     */ remote ? : boolean ; } export default class Browser extends EventEmitter { private private app : App ; private private _browserWindow ? : BrowserWindow ; /**
     * 标识符
     */ identifier : string ; /**
     * 生成时的选项
     */ options : BrowserWindowOpts ; /**
     * 对外暴露的获取窗口的方法
     */ get browserWindow ( ) { return this . retrieveOrInitialize ( ) ; } param options param application constructor ( options , application ) { super ( ) ; this . app = application ; this . identifier = options . identifier ; this . options = options ; this . retrieveOrInitialize ( ) ; this . browserWindow . on ( 'closed' , ( ) => { this . destroy ( ) ; } ) ; } param name loadUrl = ( name ) => { const { PORT = 8000 } = process . env ; if ( dev ( ) ) { this . browserWindow . loadURL ( `http://localhost:${ PORT }/#/${ name }` ) ; } else { createProtocol ( 'app' ) ; this . browserWindow . loadURL ( `app://./${ name }.html` ) ; } } ; /**
     * 加载 Dev 工具
     */ loadDevTools = ( ) => { if ( ! ( dev ( ) || process . env . DEBUG === '1' ) ) return ; app . whenReady ( ) . then ( ( ) => { const { default : installExtension , REDUX_DEVTOOLS , } = require ( 'electron-devtools-installer' ) ; const extensions = [ REDUX_DEVTOOLS , ] ; try { installExtension ( extensions ) . then ( ( name ) => { this . app . logger . trace ( `Added Extension:  ${ name }` ) ; } ) ; } catch ( e ) { this . app . logger . error ( 'An error occurred: ' , e ) ; } } ) ; } ; show ( ) { this . browserWindow . show ( ) ; } hide ( ) { this . browserWindow . hide ( ) ; } /**
     * 销毁实例
     */ destroy ( ) { this . _browserWindow = undefined ; } /**
     * 初始化
     */ retrieveOrInitialize ( ) { if ( this . _browserWindow && ! this . _browserWindow . isDestroyed ( ) ) { return this . _browserWindow ; } const { identifier , title , width , height , devTools , remote , ... res } = this . options ; this . _browserWindow = new BrowserWindow ( { ... res , width , height , title , webPreferences : { nodeIntegration : true , enableRemoteModule : remote , contextIsolation : false , } , } ) ; this . loadUrl ( identifier ) ; this . loadDevTools ( ) ; if ( devTools ) { this . _browserWindow . webContents . openDevTools ( ) ; } return this . _browserWindow ; } param eventName param data dispatchEvent < T extends keyof MainEvents > ( eventName , data ? ) { let tempName = Math . random ( ) . toString ( 36 ) . slice ( - 8 ) ; tempName = `a_${ tempName }` ; this . browserWindow . webContents . executeJavaScript ( `
        const ${ tempName } = new Event('electron:${ eventName }');
        ${ tempName }.data = ${ JSON . stringify ( data ) };
        window.dispatchEvent(${ tempName });
     ` ) ; } }