cawa-93 / vite-electron-builder

Secure boilerplate for Electron app based on Vite. TypeScript + Vue/React/Angular/Svelte/Vanilla
MIT License
2.37k stars 258 forks source link

main package test failes with electron-store #1011

Open Crease29 opened 5 days ago

Crease29 commented 5 days ago

Describe the bug The following error occurs when trying to run the test:main script with electron-store in use.

 FAIL  tests/unit.spec.ts [ tests/unit.spec.ts ]
SyntaxError: Named export 'app' not found. The requested module 'electron' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'electron';

 ❯ src/store.ts:2:31
      1| import {ipcMain, type IpcMainEvent, type IpcMainInvokeEvent} from 'electron';
      2| import Store from 'electron-store';
       |                               ^
      3|
      4| const configStore = new Store({

To Reproduce Steps to reproduce the behavior:

  1. Install electron-store
  2. Use store in main process:
    
    // packages/main/src/store.ts
    import {ipcMain, type IpcMainEvent, type IpcMainInvokeEvent} from 'electron';
    import Store from 'electron-store';

const configStore = new Store({ accessPropertiesByDotNotation: true, migrations: { '0.0.1': store => { store.clear(); }, }, });

ipcMain.on('set-store', (event: IpcMainEvent, args) => { configStore.set({[args.key]: args.value}); });

ipcMain.handle('get-store', (event: IpcMainInvokeEvent, key: string) => { return configStore.get(key); });

ipcMain.handle('has-store', (event: IpcMainInvokeEvent, key: string) => { return configStore.has(key); });

ipcMain.handle('delete-store', (event: IpcMainInvokeEvent, key: string) => { return configStore.delete(key); });

export {configStore};

```js
// packages/main/src/index.ts
// ...
import './store'; // Add to imports
// ...
  1. Add ipcMain mock to unit.spec.ts

    vi.mock('electron', () => {
    // Use "as unknown as" because vi.fn() does not have static methods
    const bw = vi.fn() as unknown as MockedClass<typeof BrowserWindow>;
    bw.getAllWindows = vi.fn(() => bw.mock.instances);
    bw.prototype.loadURL = vi.fn((_: string, __?: Electron.LoadURLOptions) => Promise.resolve());
    bw.prototype.loadFile = vi.fn((_: string, __?: Electron.LoadFileOptions) => Promise.resolve());
    // Use "any" because the on function is overloaded
    bw.prototype.on = vi.fn<never>();
    bw.prototype.destroy = vi.fn();
    bw.prototype.isDestroyed = vi.fn();
    bw.prototype.isMinimized = vi.fn();
    bw.prototype.isMaximized = vi.fn();
    bw.prototype.focus = vi.fn();
    bw.prototype.restore = vi.fn();
    
    const app: Pick<Electron.App, 'getAppPath'> = {
    getAppPath(): string {
      return '';
    },
    };
    const ipcMain: Pick<Electron.IpcMain, 'on' | 'handle'> = {
    on: vi.fn(),
    handle: vi.fn(),
    };
    
    return {BrowserWindow: bw, app, ipcMain};
    });
  2. Run npm run test:main

Expected behavior The test should run through, even with external libraries being used. If there's something to add to the electron mock in packages/main/tests/unit.spec.ts when using external libraries, it would be nice to add that to a documentation.

Screenshots image

Additional context I'm using the latest version of this template.

cawa-93 commented 1 day ago

Hi. I tried to reproduce this issue step by step as you describe, but I didn't see any issues.

Crease29 commented 1 day ago

I will provide you with an example repository tomorrow.