Reputation: 1
I'm completely new to Electron, and am currently developing an application (using Electron-Vite + React) and encountering an issue related to loading a local resource (specifically a file named video.html) into a secondary BrowserWindow. While I can load the index.html file without any problems using Electron's loadURL function, I consistently face the "Unable to load local resource" error when attempting to load video.html.
The app is working fine in development environment using npm run dev
, but as soon as I preview the production with npm start
the second BrowserWindow throws an error at me.
Here is my index.js main process file
//index.js
import { app, shell, BrowserWindow, ipcMain } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
let mainWindow, secondWindow
function createWindow() {
mainWindow = new BrowserWindow({
width: 900,
height: 670,
show: false,
autoHideMenuBar: true,
...(process.platform === 'linux' ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
contextIsolation: true,
enableRemoteModule: false,
webSecurity: true
}
})
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
})
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/index.html`)
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
}
}
function createSecondWindow() {
secondWindow = new BrowserWindow({
width: 1080,
height: 720,
autoHideMenuBar: true,
...(process.platform === 'linux' ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
contextIsolation: true,
enableRemoteModule: false,
webSecurity: true
}
})
secondWindow.on("ready-to-show", () => {
secondWindow.show();
});
secondWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
})
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
secondWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/video.html`)
} else {
secondWindow.loadFile(join(__dirname, '../renderer/video.html'));
}
}
app.whenReady().then(() => {
electronApp.setAppUserModelId('com.electron')
app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window)
})
createWindow()
createSecondWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
ipcMain.on("play-video", (event, videoPath) => {
if (secondWindow) {
secondWindow.webContents.send("start-video", videoPath);
}
})
Electron.vite.config.js
import { resolve } from 'path'
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
main: {
plugins: [externalizeDepsPlugin()]
},
preload: {
plugins: [externalizeDepsPlugin()]
},
renderer: {
resolve: {
alias: {
'@renderer': resolve('src/renderer/src')
}
},
plugins: [react()]
},
})
The structure of my application is as follows:
├── build
├── out
└─┬ src
├── preload
├─┬ main
│ └── index.js
├─┬ renderer
│ ├── index.html
│ ├── video.html
│ ├── public
│ └─┬ src
│ ├── App.jsx (React component used in main.jsx)
│ ├── VideoApp.jsx (React component used in video.jsx)
│ ├── main.jsx (src for index.html)
│ └── video.jsx (src for video.html)
├── electron.vite.config.js
└── package.json
Could someone guide me on how to load video.html into a BrowserWindow without encountering this "Unable to load local resource" error?
What I've Tried:
Using loadFile and loadURL: I attempted loading the file directly into the window using Electron's loadFile and loadURL methods. However, both approaches resulted in the same error.
Adjusting Security Settings: I ensured that my Electron security settings (webSecurity, etc.) were correctly configured but still encountered the same problem.
Upvotes: 0
Views: 617
Reputation: 1
It appears that I had missed one part of the documentation in my search of a solution. For now, the solution seems to be just to modify my config file:
import { resolve } from 'path'
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
main: {
plugins: [externalizeDepsPlugin()]
},
preload: {
plugins: [externalizeDepsPlugin()]
},
renderer: {
//ADDED THE BUILD.ROLLUPOPTIONS.INPUT FOR BOTH RENDERER PROCESSES
build: {
rollupOptions: {
input: {
browser: resolve(__dirname, 'src/renderer/index.html'),
webview: resolve(__dirname, 'src/renderer/video.html')
}
}
},
resolve: {
alias: {
'@renderer': resolve('src/renderer/src')
}
},
plugins: [react()]
},
})
With this modification I was able to get the secondWindow to work in both development and production. Now I just need to troubleshoot the ipcMain as the communication between the two windows breaks down after these changes.
Upvotes: 0