diff --git a/electron/main/index.ts b/electron/main/index.ts index f9120757..2d0d224e 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -55,7 +55,7 @@ async function createWindow() { // Consider using contextBridge.exposeInMainWorld // Read more on https://www.electronjs.org/docs/latest/tutorial/context-isolation - contextIsolation: false, + // contextIsolation: false, }, }) diff --git a/electron/preload/index.ts b/electron/preload/index.ts index ebf1276f..612e19a8 100644 --- a/electron/preload/index.ts +++ b/electron/preload/index.ts @@ -1,3 +1,28 @@ +import { ipcRenderer, contextBridge } from 'electron' + +// --------- Expose some API to the Renderer process --------- +contextBridge.exposeInMainWorld('ipcRenderer', withPrototype(ipcRenderer)) + +// `exposeInMainWorld` can't detect attributes and methods of `prototype`, manually patching it. +function withPrototype(obj: Record) { + const protos = Object.getPrototypeOf(obj) + + for (const [key, value] of Object.entries(protos)) { + if (Object.prototype.hasOwnProperty.call(obj, key)) continue + + if (typeof value === 'function') { + // Some native APIs, like `NodeJS.EventEmitter['on']`, don't work in the Renderer process. Wrapping them into a function. + obj[key] = function (...args: any) { + return value.call(obj, ...args) + } + } else { + obj[key] = value + } + } + return obj +} + +// --------- Preload scripts loading --------- function domReady(condition: DocumentReadyState[] = ['complete', 'interactive']) { return new Promise((resolve) => { if (condition.includes(document.readyState)) { diff --git a/src/demos/ipc.ts b/src/demos/ipc.ts index b94a9392..ba4daa0c 100644 --- a/src/demos/ipc.ts +++ b/src/demos/ipc.ts @@ -1,5 +1,4 @@ -import { ipcRenderer } from 'electron' -ipcRenderer.on('main-process-message', (_event, ...args) => { +window.ipcRenderer.on('main-process-message', (_event, ...args) => { console.log('[Receive Main-process message]:', ...args) }) diff --git a/src/main.ts b/src/main.ts index 8924aee7..4a868581 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,9 +3,9 @@ import App from './App.vue' import './style.css' -// `nodeIntegration` needs to be enabled in the Main process. +import './demos/ipc' +// If you want use Node.js, the`nodeIntegration` needs to be enabled in the Main process. // import './demos/node' -// import './demos/ipc' createApp(App) .mount('#app') diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 323c78a6..788532e7 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -5,3 +5,8 @@ declare module '*.vue' { const component: DefineComponent<{}, {}, any> export default component } + +interface Window { + // expose in the `electron/preload/index.ts` + ipcRenderer: import('electron').IpcRenderer +}