Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node Integration is set to false, but I need the renderer process and the main process communication #5113

Closed
Luncher opened this issue Apr 11, 2016 · 14 comments

Comments

@Luncher
Copy link

Luncher commented Apr 11, 2016

  • Electron version:
  • Operating system:

In order to simulate the real browser environment, I put node Integration is set to false, but I need the renderer process and the main process communication, how can I do it?

@baconbrad
Copy link
Contributor

You can't. This is by design. It doesn't have access to process and IPC since those are only available because of the Node context.

To achieve what you want to do you need nodeIntegration enabled. I have wrote apps that work in both contexts and take advantage of the Node context if available by detecting if window.process is defined.

@baconbrad
Copy link
Contributor

However there might be a way around it. I haven't tested this yet but you might be able to have a nodeIntegration false BrowserWindow emit events your main.js can listen to. From there it can handle it in the Node context. And then if needed can manipulate or execute code in the BrowserWindow via the main.js. You won't be able to to use IPC but it would set up some form of communication.

@anaisbetts
Copy link
Contributor

@Luncher Create a preload script:

window.ipc = require('ipc')

@baconbrad
Copy link
Contributor

Ha @paulcbetts, I was just returning to this to say the preload script can do this. I was unaware it still had access to the Node context until I started digging into a workaround for this. So disregard what I previously said @Luncher.

@Luncher
Copy link
Author

Luncher commented Apr 12, 2016

@paulcbetts window.ipc = require ( 'ipc') can be put where?

@baconbrad
Copy link
Contributor

When you spawn your browser window set the preload option to a script you wish to preload:

webPreferences: {
    nodeIntegration: false,
    preload: "preload.js"
}

Then in the preload script put in window.ipc = require('ipc'). Do your IPC communication in the preload.js and have the code interact with your browser window as if it was loaded using script tags.

@baconbrad
Copy link
Contributor

The docs also indicate the preload script must have an absolute path.

@Luncher
Copy link
Author

Luncher commented Apr 12, 2016

thanks @baconface

@zcbenz zcbenz closed this as completed Apr 12, 2016
@akashnimare
Copy link

@paulcbetts is there any way I could use require in renderer process while nodeintegration is set to false?

@MarshallOfSound
Copy link
Member

@akashnimare Why... If you insert require into the global scope with nodeIntegration disabled you may as well just turn on nodeIntegration...

@baconbrad
Copy link
Contributor

baconbrad commented Sep 27, 2016

Here is also an alternate way of doing things if the above isn't quite what you wish to do. We have had some issues doing exactly what we wanted with the preload.js and nodeIntegration false stuff. It was mostly scope issues. Our end goal was to have an Electron app but also load the same code base in a browser. So now we have nodeIntegration set to true and do the following and it might work for you too.

First we require all our Electron stuff (this must be the first JavaScript to run):

if (typeof module === 'object') {
  // Require Electron, IPC, other modules here
  window.module = module;
  module = undefined;
}

Undefining the module now makes it load third party dependencies in a normal browser context opposed to a node context.

If we do anything that requires Electron we do a check for it. This isn't exactly what we use but it could work for you:

function isElectron() {
 return navigator.userAgent.indexOf('Electron') !== -1;
}

Usuage:

if (isElectron()) {
  // Do Electron stuff
}

Just remember doing this it means that when using it in Electron node is always "hot". And if you run third party scripts you risk them getting file system access, etc.

@donaldpipowitch
Copy link

Hi there! I recently started to use Electron again, after a couple of years. Electron v5 defaults to nodeIntegration: false and this seems to be the recommended setting, right?

Is there an obvious advantage I can't see in using a preload script to set window.ipc = require('ipc') instead of maybe launching a server in the main process which I can make requests against with a regular fetch?

@baconbrad
Copy link
Contributor

Hi there! I recently started to use Electron again, after a couple of years. Electron v5 defaults to nodeIntegration: false and this seems to be the recommended setting, right?

Yes, years ago Electron opened everything up as much as possible. Now all the settings are set to close everything with security in mind. Developers can lift security restrictions as they see fit.

Is there an obvious advantage I can't see in using a preload script to set window.ipc = require('ipc') instead of maybe launching a server in the main process which I can make requests against with a regular fetch?

You may run into issues where the target machine cannot properly start the server due to network config issues, used ports, etc. Or requests might timeout for whatever reason or the server could be blocked by the user's firewall. There may be a reason you would want to use a local server but if it is just for communication between the main process and render process it seems a bit overkill and not as efficient in comparison to IPC.

@donaldpipowitch
Copy link

Thank you for the feedback. Very useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants