0

I'm trying to write results of an electron/vue app to a file.

          const fs = require("fs");
      try {
        fs.writeFileSync(
          "myfile.txt",
          "the text to write in the file",
          "utf-8"
        );
      } catch (e) {
        alert(`Failed to save the file ${e}!`);
      }

As suggested here: Saving files locally with electron

But I get an error: fs.writeFileSync does not exist.

How can I get this to work?

MPL
  • 384
  • 1
  • 4
  • 20
  • you don't use import statement for use libraries ? do you use vue-cli plugins for create your project ? – miltone Feb 02 '21 at 16:16
  • @darkomen - The require statement you can see as the first line. I'm not aware of any vue-cli plugins??? – MPL Feb 02 '21 at 16:19
  • this vue-cli command : 'vue create vue-electron-app' can easily help you to create a base project for more easily do what you want. – miltone Feb 02 '21 at 16:24
  • @darkomen - I see, yes I use vue-cli. – MPL Feb 02 '21 at 16:28
  • I see now that fs is not for browser usage. Does this mean that there is no way to save files for use by the user in a electron app browser side? – MPL Feb 02 '21 at 16:34
  • perhaps send a IPC message to the main process for writing file – miltone Feb 02 '21 at 17:06

1 Answers1

0

The scripts running in web contexts don't have access to node or electron functionality by default as a security precaution. It's hard to find good samples for the current version, there are too many outdated or non-working samples out there. I have a sample repo where I communicate with the main thread to show an open file dialog and display the selected name and contents if you're interested.

The current way (Vue3, electron13) looks to be using context isolation, creating a preload script that runs in the render thread and has access to node and electron functionality.

1. Add configuration to vue.config.js

This adds a src/preload.js script as a preload script to pluginOptions.electronBuilder.

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  pluginOptions: {
    electronBuilder: {
      preload: 'src/preload.js'
    }
  }
});

2. Setup our plugin script in background.js

When creating the window, add the preload script:

  // Create the browser window.
  const win = new BrowserWindow({
    width: 1920,
    height: 1080,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      enableRemoteModule: false,
      preload: path.join(__dirname, 'preload.js') // add preload script
    }
  })

3. Add src/preload.js script

In this script we have more privileges and can use node functionality like 'fs'. We can expose our own api to the web scripts:

import { contextBridge } from 'electron'
import fs from 'fs'

contextBridge.exposeInMainWorld('file', {
  save: (filePath, text) => {
    fs.writeFileSync(filePath, text, { encoding: 'utf-8' });
  }
});

4. Use window.file.save() in your code

try {
  window.file.save('myfile.txt', 'the text to write to the file');
} catch (e) {
  alert(`Failed to save the file ${e}!`);
}
Jason Goemaat
  • 28,692
  • 15
  • 86
  • 113