Igino Boffa
Igino Boffa

Reputation: 736

Using ipcRenderer in Angular 15 + Electron 22 project causes building errors

I am trying to use ipcRenderer in an Angular service. My project will only work in an Electron environment. If I try to use the standard builder, I get the following error:

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
        - install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "path": false }

If I use the esbuild builder, this is what I get:

X [ERROR] Could not resolve "fs"

    node_modules/electron/index.js:1:19:
      1 │ const fs = require('fs');
        ╵                    ~~~~

  The package "fs" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

I tried to put

"platform: 'node'"

Both in tsconfig file and angular.json file, but it seems like it is not a valid option.

If I add this block to package.json:

 "browser": {
    "path": false,
    "fs": false
  }

Then I have the following error at runtime:
ERROR Error: Uncaught (in promise): ReferenceError: __dirname is not defined

Even though I haven't used __dirname anywhere in the browser code.

What should I do to make it work?

Upvotes: 0

Views: 1097

Answers (2)

Tanishq Garg
Tanishq Garg

Reputation: 11

you are seeing this error because when you write

import ipcRenderer from 'electron'

in any renderer process, you expose all the functionality to it even though renderer process does not have access to Node.js environment so don't write the above mentioned line of code in any renderer process. if you wish to use ipcRenderer, wrap it inside a helper function like this

in preload script file:

.....
    if (process.contextIsolated) {
      try {
        contextBridge.exposeInMainWorld('ipcapi', {
          send:(channel,data)=>ipcRenderer.send(channel,data),  
          on:(channel,func)=> ipcRenderer.on(channel,(event,...args)=>func(...args)),
        });
      } catch (error) {
        console.error(error)
      }
    } else {
      window.api = {
        send:(channel,data)=>ipcRenderer.send(channel,data),  
        on:(channel,func)=> ipcRenderer.on(channel,(event,...args)=>func(...args)),
      }
    }

and now in your renderer process, access it like:

............
const ipcrend=window.ipcapi  
      const loginhandler = () => {
        const data={Usern,Passw}
        console.log(data)
        ipcrend.send("login",data)
      }

hope it helps!

Upvotes: 0

GreyBeardedGeek
GreyBeardedGeek

Reputation: 30088

Electron has two separate processes - the render process, which runs in the bundled web browser (the ipcRenderer), and the main process, which runs in a node.js process.

As such, you can use core node.js modules in the main process, but not in the ipcRenderer since these modules (e.g. fs) are not available in the browser.

It sounds like you're trying to use fs in the renderer (your Angular app). That's not going to work.

If you want to, for example, read data from the file system and display it in the browser, you're going to have to use Electron's interprocess communications to have the Angular ask the main process to read the file, and then pass the content back to the renderer from the main process asynchronously.

Upvotes: 1

Related Questions