How to use FS module inside Electron.Atom\WebPack application?

33,765

Solution 1

Problem is solved.

Need use in electron app (where you add the bundle):

var remote = require('electron').remote;
var electronFs = remote.require('fs');
var electronDialog = remote.dialog;

Solution 2

In addition to the accepted answer.

If you are using Webpack (like when you are using Angular, React or other frameworks) require will be resolved by webpack, which will screw it's usage at runtime.

Use window.require instead.

Ex:

var remote = window.require('electron').remote;
var electronFs = remote.require('fs');
var electronDialog = remote.dialog;

Note: There is no need to use remote in order to access any of Node API from a renderer process as it's fully exposed.

const fs = window.require('fs');
const path = window.require('path');

will do.

Update

Starting from v5 of Electron, the Node API is no longer exposed by default in the renderer process!

The default for the nodeIntegration flag changed from true to false.

You can enable it when creating the Browser Window:

app.on('ready', () => {
    mainWindow = new BrowserWindow({
        webPreferences: {
            nodeIntegration: true, // <--- flag
            nodeIntegrationInWorker: true // <---  for web workers
        }
    });
});

The security risk of activating nodeIntegration

nodeIntegration: true is a security risk only when you're executing some untrusted remote code in your application. For example, suppose your application opens up a third party webpage. That would be a security risk because the third party webpage will have access to node runtime and can run some malicious code on your user's filesystem. In that case it makes sense to set nodeIntegration: false. If your app is not displaying any remote content, or is displaying only trusted content, then setting nodeIntegration: true is okay.

And finally, the recommended secure way from the doc:

https://electronjs.org/docs/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content

Share:
33,765
Max
Author by

Max

Updated on July 09, 2022

Comments

  • Max
    Max almost 2 years

    I need write some data in the file, using FS module (fs.writeFile). My stack is webpack + react + redux + electron.

    The first problem was: Cannot resolve module 'fs'. I tried to use

    target: "node",
    ---
    node: {
        global: true,
        fs: "empty",
    }
    ---
    resolve: {
        root: path.join(__dirname),
        fallback: path.join(__dirname, 'node_modules'),
        modulesDirectories: ['node_modules'],
        extensions: ['', '.json', '.js', '.jsx', '.scss', '.png', '.jpg', '.jpeg', '.gif']
    },
    

    After several attempts, the problem is resolved ( node: {fs: "empty"} ). But then there was a second problem: screenshot.

    //In method componentDidMount (React)
    console.log('fs', fs);
    console.log('typeOf', typeof fs.writeFile);
    
    //By clicking on the button
    console.log(fs);
    console.log(typeof fs.writeFile);
    

    You can see, that fs is empty object, and method writeFile no exists. I tried to change the webpack's configuration.

    const path = require('path');
    const fs = require('fs');
    const webpack = require("webpack");
    console.log(fs);
    

    In this case fs is not empty.

    How to solve this problem? Any ideas?

  • nxheller
    nxheller almost 7 years
    did you add this to your main Electron process (i.e. main.js)? I added these definitions, but don't know what to do with them...
  • Tyler Collier
    Tyler Collier almost 7 years
    Be sure to read up on electron.remote: "In Electron, GUI-related modules (such as dialog, menu etc.) are only available in the main process, not in the renderer process. In order to use them from the renderer process, the ipc module is necessary to send inter-process messages to the main process. With the remote module, you can invoke methods of the main process object without explicitly sending inter-process messages"