ci010 / electron-vue-next

A starter template for using vue-next with the electron.
https://ci010.github.io/electron-vue-next/
191 stars 27 forks source link

electron.ipcRenderer.on is undefined #49

Closed 2234839 closed 3 years ago

2234839 commented 3 years ago

I made the following choice, and then without changing a single line of code, after starting ipcRenderer could not access on 图片

图片 图片

It looks like the event-related code is not appended

system info

versions: 1.55.0-insider (system setup) commit: d06d2f1d6245ce00b1c36a9cd81a9087d225173e date: 2021-03-26T14:01:14.867Z Electron: 11.3.0 Chrome: 87.0.4280.141 Node.js: 12.18.3 V8: 8.7.220.31-electron.0 OS: Windows_NT x64 10.0.19042

ci010 commented 3 years ago

After I investigated it for awile, I think this is caused by contextIsolation of the BrowserWindow

const mainWindow = new BrowserWindow({
    height: 600,
    width: 800,
    webPreferences: {
      preload: __preloads.index,
      contextIsolation: true, // change this to false to make "ipcRenderer.on" accessable!
      nodeIntegration: false
    }
  })

So the workaround is changing it to false...

Not sure if this is by-design for electron.

2234839 commented 3 years ago

After I investigated it for awile, I think this is caused by contextIsolation of the BrowserWindow

const mainWindow = new BrowserWindow({
    height: 600,
    width: 800,
    webPreferences: {
      preload: __preloads.index,
      contextIsolation: true, // change this to false to make "ipcRenderer.on" accessable!
      nodeIntegration: false
    }
  })

So the workaround is changing it to false...

Not sure if this is by-design for electron.

Thank you very much!

ci010 commented 3 years ago

Thanks to raise the issue, and I fix this by adding a wrapper in src\preload\index.ts.

In 0.0.11, it will ship with the following wrapper (and this is easy to remove):

/**
 * Wrapper of ipc renderer.
 *
 * So the `contextIsolation: true` won't prevent you to use method inherit from EventEmitter,
 * lile `ipcRenderer.on`
 */
const _ipcRenderer: IpcRenderer = {
  invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args),
  on: (channel, listener) => {
    ipcRenderer.on(channel, listener)
    return _ipcRenderer
  },
  once: (channel, listener) => {
    ipcRenderer.once(channel, listener)
    return _ipcRenderer
  },
  postMessage: (channel, message, transfers) => ipcRenderer.postMessage(channel, message, transfers),
  removeAllListeners: (channel) => {
    ipcRenderer.removeAllListeners(channel)
    return _ipcRenderer
  },
  removeListener: (channel, listener) => {
    ipcRenderer.removeListener(channel, listener)
    return _ipcRenderer
  },
  send: (channel, ...args) => ipcRenderer.send(channel, ...args),
  sendSync: (channel, ...args) => ipcRenderer.send(channel, ...args),
  sendTo: (id, channel, ...args) => ipcRenderer.sendTo(id, channel, ...args),
  sendToHost: (channel, ...args) => ipcRenderer.sendToHost(channel, args),
  // event emitter methods
  setMaxListeners: (n) => {
    ipcRenderer.setMaxListeners(n)
    return _ipcRenderer
  },
  getMaxListeners: () => ipcRenderer.getMaxListeners(),
  listeners: (e) => ipcRenderer.listeners(e),
  rawListeners: (e) => ipcRenderer.rawListeners(e),
  emit: (e, ...args) => ipcRenderer.emit(e, ...args),
  listenerCount: (e) => ipcRenderer.listenerCount(e),
  addListener: (e, l) => {
    ipcRenderer.addListener(e, l)
    return _ipcRenderer
  },
  off: (e, l) => {
    ipcRenderer.off(e, l)
    return _ipcRenderer
  },

  prependListener: (e, l) => {
    ipcRenderer.prependListener(e, l)
    return _ipcRenderer
  },
  prependOnceListener: (e, l) => {
    ipcRenderer.prependOnceListener(e, l)
    return _ipcRenderer
  },
  eventNames: () => ipcRenderer.eventNames()
}