es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

No se puede resolver “fs” en \node_modules\electron.

Estoy utilizando la estructura de electron-react y quiero utilizar un diálogo de electron en App.tsx:

const { dialog } = require('@electron/remote') //también lo intenté con import

const Hello = () => {
  const readFromFile = async () => {
    dialog.showOpenDialog({})
  }
  return (
    <>
      <button onclick="{()" ==""> readFromFile()}>Probar</button>

  )
}
<code>
En main.ts coloqué la siguiente línea al comienzo
</code>
require('@electron/remote/main').initialize()

Al final siempre obtengo este error:

Module not found: Error: Can’t resolve ‘fs’ in ‘C:\Users\myUsername\source\repos\electronTest\node_modules\electron’

También intenté con nodeIntegration: true y contextIsolation: false.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error “Module not found: Error: Can’t resolve ‘fs'” típicamente ocurre al tratar de usar módulos de Node.js en el proceso del renderer de una aplicación Electron sin habilitar la integración de Node.js en Electron.

    Para solucionar este problema, puedes probar agregando el siguiente código a tu archivo main.ts:

    app.allowRendererProcessReuse = false; // agrega esta línea antes de la línea app.on('ready', () => {...})
    
    protocol.registerSchemesAsPrivileged([{
      scheme: 'app',
      privileges: {
        secure: true,
        standard: true,
      },
    }]);
    
    let mainWindow: BrowserWindow | null = null;
    
    function createWindow() {
      mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: true, // agrega esta línea para activar la integración de Node.js
          contextIsolation: false,
          enableRemoteModule: true,
        },
      });
    
      mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);
      mainWindow.on('closed', () => {
        mainWindow = null;
      });
    }
    
    app.on('ready', () => {
      createWindow();
    });
    
    app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        app.quit();
      }
    });
    
    app.on('activate', () => {
      if (mainWindow === null) {
        createWindow();
      }
    });
    

    Alternativamente, puedes usar la API contextBridge para exponer de manera segura el módulo dialog al proceso del renderer, sin activar la integración completa de Node.js.

    Para hacerlo, puedes modificar tu archivo preload.ts de la siguiente manera:

    import { contextBridge, ipcRenderer } from 'electron';
    
    contextBridge.exposeInMainWorld('electron', {
      dialog: {
        showOpenDialog: (options: Electron.OpenDialogOptions) => {
          ipcRenderer.invoke('show-open-dialog', options);
        }
      }
    });
    

    Luego, en tu archivo App.tsx, puedes usar el módulo dialog de la siguiente manera:

    const { dialog } = window.electron;
    
    const Hello = () => {
      const readFromFile = async () => {
        dialog.showOpenDialog({});
      }
      return (
        <>
          <button onclick="{()" ==""> readFromFile()} >Test</button>
    
      )
    }
    

    En tu archivo main.ts, puedes agregar el siguiente código para manejar el evento IPC show-open-dialog y mostrar el dialog en el proceso principal:

    ipcMain.handle('show-open-dialog', async (event, options: Electron.OpenDialogOptions) => {
      const result = await dialog.showOpenDialog(options);
      return result.filePaths;
    });
    

    Ten en cuenta que el uso de contextBridge proporciona una forma más segura de exponer las APIs seleccionadas de Electron que activar la integración completa de Node.js.

Comments are closed.