diff --git a/preload/index.main.ts b/preload/index.main.ts index bbd78e8..178376c 100644 --- a/preload/index.main.ts +++ b/preload/index.main.ts @@ -1,16 +1,20 @@ import fs from 'fs' import path from 'path' import { contextBridge, ipcRenderer } from 'electron' -import { domReady } from './utils' +import { domReady, injectWsCode } from './utils' import { useLoading } from './loading' +const isDev = process.env.NODE_ENV === 'development' const { appendLoading, removeLoading } = useLoading() - ; (async () => { await domReady() appendLoading() + isDev && injectWsCode({ + host: '127.0.0.1', + port: process.env.PORT_WS as string, + }) })(); // --------------------------------------------------- diff --git a/preload/utils.ts b/preload/utils.ts index 7dd3280..5405abf 100644 --- a/preload/utils.ts +++ b/preload/utils.ts @@ -13,3 +13,37 @@ export function domReady(condition: DocumentReadyState[] = ['complete', 'interac } }) } + +/** Inject ws related code */ +export function injectWsCode(options: { + host: string + port: string | number +}) { + const oScript = document.createElement('script') + oScript.id = 'ws-preload-hot-reload' + + oScript.innerHTML = ` +${__ws_hot_reload_for_preload.toString()} +${__ws_hot_reload_for_preload.name}(${JSON.stringify(options)}) +` + + document.body.appendChild(oScript) +} + +function __ws_hot_reload_for_preload(options: { host: string; port: string | number }) { + const ws = new WebSocket(`ws://${options.host}:${options.port}`) + ws.onmessage = function (ev) { + try { + console.log('[preload] ws.onmessage:', ev.data) + + const data = JSON.parse(ev.data) // { "cmd": "string", data: "string|number" } + + if (data.cmd === 'reload') { + setTimeout(() => window.location.reload(), 999) + } + } catch (error) { + console.warn(`ws.onmessage should be accept "JSON.string" formatted string.`) + console.error(error) + } + } +} diff --git a/scripts/dev.ts b/scripts/dev.ts index 5386765..a908d46 100644 --- a/scripts/dev.ts +++ b/scripts/dev.ts @@ -1,21 +1,26 @@ +process.env.NODE_ENV = 'development' + import { join } from 'path' -import { spawn, ChildProcess } from 'child_process' import electron from 'electron' -import { RollupWatcher, RollupWatcherEvent, watch } from 'rollup' +import { spawn, ChildProcess } from 'child_process' import { createServer as createViteServer } from 'vite' +import { RollupWatcher, RollupWatcherEvent, watch } from 'rollup' +import WebSocket from 'ws' +import chalk from 'chalk' import pkg from '../package.json' import { mainOptions, preloadOptions, } from './utils' +import { createWsServer, formatWsSendData } from './ws' -const TAG = '[dev.ts]' +const TAG = chalk.bgGray('[dev.ts]') function eventHandle(ev: RollupWatcherEvent) { if (ev.code === 'ERROR') { - console.error(TAG, ev.error) + console.error(TAG, chalk.red(ev.error)) } else if (ev.code === 'BUNDLE_START') { - console.log(TAG, `Rebuild - ${ev.output}`) + console.log(TAG, chalk.blue(`Rebuild - ${ev.output}`)) } } @@ -41,10 +46,16 @@ function watchMain(): RollupWatcher { } function watchPreload(): RollupWatcher { + const wssObj = createWsServer({ TAG }) + return watch(preloadOptions()) .on('event', ev => { if (ev.code === 'END') { - // TODO Hot reload + // Hot reload renderer process !!! + if (wssObj.instance?.readyState === WebSocket.OPEN) { + console.log(TAG, chalk.yellow('Hot reload renderer process')) + wssObj.instance.send(formatWsSendData({ cmd: 'reload', data: Date.now() })) + } } eventHandle(ev) @@ -59,11 +70,11 @@ function watchPreload(): RollupWatcher { })).listen() const { host = '127.0.0.1', port = 3000 } = server.config.server - console.log(TAG, `Server run at - http://${host}:${port}`) + console.log(TAG, chalk.yellow(`Server run at - http://${host}:${port}`)) watchPreload() watchMain() } catch (error) { - console.error(TAG, error) + console.error(TAG, chalk.red(error)) } })(); diff --git a/scripts/ws.ts b/scripts/ws.ts new file mode 100644 index 0000000..c00e6f9 --- /dev/null +++ b/scripts/ws.ts @@ -0,0 +1,43 @@ +/** + * Hot reload from preload script during development + */ +import WebSocket from 'ws' +import chalk from 'chalk' +import pkg from '../package.json' + +export interface CreateWsServerOptions { + TAG: string +} + +export function createWsServer(options: CreateWsServerOptions) { + const { TAG } = options + const port = pkg.env.PORT_WS + const host = pkg.env.HOST || '127.0.0.1' + const wss = new WebSocket.Server({ host, port }) + const wssObj: { wss: WebSocket.Server; instance: WebSocket | null } = { wss, instance: null } + + console.log(TAG, 'Wss run at - ' + chalk.yellow(`ws://${host}:${port}`)) + + wss.on('connection', ws => { + console.log(TAG, chalk.yellow(`wss.on('connection')`)) + + wssObj.instance = ws + ws.on('message', message => { + console.log(TAG, `ws.on('message'):`, message.toString()) + }) + + ws.send(formatWsSendData({ cmd: 'message', data: 'connected.' })) + }) + + wss.on('close', () => { + console.log(TAG, chalk.gray(`wss.on('close')`)) + + wssObj.instance = null + }) + + return wssObj +} + +export function formatWsSendData(json: { cmd: string, data?: any }) { + return JSON.stringify(json) +}