ES6 import of electron modules with Vite/Vue fails
Asked Answered
C

2

8

I am trying to use electron with latest Vite 2/Vue 3. I have setup two versions of electron's main file so I can test and work with both dev server and the build:

  • dev version loading the localhost:3000 (from npm run dev) with loadURL
  • another version loading the built version (from npm run build)from the dist folder with loadFile

I have set in the new BrowserWindow options:

webPreferences: {
   nodeIntegration: true,
   contextIsolation: false,
   enableRemoteModule: true,
   preload: path.join(app.getAppPath(), 'electron.preload.js')
}

The app starts just fine in Electron in both dev and build version, loads all assets and without any security errors. However, when I try to import any module from 'electron' in my project, in example:

import electron from 'electron';

I get the error:

Uncaught TypeError: path.join is not a function
    at node_modules/electron/index.js (index.js:4)

I tried to check path and __dirname, to see if they work in my project:

import * as path from 'path';

console.log(path);
console.log(path.join);
console.log(__dirname);

And these do trace out the following in Electron dev panel:

enter image description here

If I try to import path differntly:

import path from 'path'
console.log(path);
console.log(path.join);

I get the following result:

enter image description here

In any case, path.join is undefined. And now I am pretty much stuck on how to go on.

I can also add that I want to use fs-extra, but this also fails:

import fs from 'fs-extra';

enter image description here

[Edit: added the preload in webPreferences]

Corbie answered 1/11, 2021 at 13:14 Comment(2)
Did you ever find a solution to this error? I have a similar problem.Harbin
Not really, using require() to make it work e.g. >> const { app } = require('@electron/remote');Corbie
B
1

I believe Vite transforms things a lot behind the scenes. Thankfully @electron/remote provides an alternate way to fetch things:

electron.js:

const { app, BrowserWindow } = require("electron");
const Remote = require("@electron/remote/main");

Remote.initialize();

// ...

app.on("ready", () => {
  mainWindow = new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
      enableRemoteModule: true,
      contextIsolation: false,
    },
  });

  Remote.enable(mainWindow.webContents);

  mainWindow.loadFile(path.resolve("./dist", "index.html"));
});

// ...

Component.tsx:

import type { BrowserWindow } from "electron";


const Component: React.FC = () => {
  const app = window.require("@electron/remote");
  const win: BrowserWindow = app.getCurrentWindow();

  // ...
}

Not sure if this is the best solution, but it works for me with Vite + Electron + React.

Burthen answered 17/4, 2022 at 8:34 Comment(0)
C
0

In my case preload resolved the issue

import { contextBridge, nativeImage } from 'electron';

if (process.contextIsolated) {
  try {
    contextBridge.exposeInMainWorld('nativeImage', nativeImage);
  } catch (error) {
    console.error(error);
  }
} else {
  window.nativeImage = nativeImage;
}

And then in vue side just use

window.nativeImage

Confectioner answered 14/6, 2023 at 16:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.