electron-serve
electron-serve copied to clipboard
Error: ERR_FILE_NOT_FOUND (-6) loading 'app://-/'
I have an electron-forge setup that I want to add electron-serve to.
I tried creating a /renderer
directory and putting an index.html in it and using this code
const loadURL = serve({ directory: "renderer" });
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 1600,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
// and load the index.html of the app.
// original electron-forge command
// mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY)
loadURL(mainWindow);
// Open the DevTools.
// mainWindow.websContents.openDevTools();
};
But I end up with
UnhandledPromiseRejectionWarning: Error: ERR_FILE_NOT_FOUND (-6) loading 'app://-/'
at rejectAndCleanup (electron/js2c/browser_init.js:217:1457)
at Object.failListener (electron/js2c/browser_init.js:217:1670)
at Object.emit (events.js:315:20)
Am I missing something simple?
Hi! @simonh1000 I was having the same problem today, I don't know but looks like if I wait for a answer it will be too late, so here is what I did:
I copied the index.js
content of this package into my project to a new file serve.js
in the same directory as the electron main file.
In the electron main file, instead of use:
const serve = require('electron-serve');
I used:
const serve = require('./serve');
And now I just edited the serve.js
file, at the end of file (line 75 for me) you will have:
return async window_ => { await window_.loadURL(`${options.scheme}://-`); };
Note that this return is just where our problem is, so I changed it to:
return async (window_) => { await window_.loadURL(`${options.scheme}://${options.directory}`); };
And now everything works! In my case I'm using a script to build a react app, and electron serves the build folder, so I have to use the 'app' scheme, here is my serve options:
const loadURL = serve({ directory: 'build', scheme: 'app' });
In YOUR case, I think you are trying to serve static files without the single page application routing stuff, so your serve options may be like:
const loadURL = serve({ directory: 'renderer/index.html', scheme: 'file' });
If you need the routing fallbacks, use 'app' as the scheme and just leave your renderer directory without specifying the entry point.
Tell me if it works for you! For me it's fully functional by now.
@sindresorhus Is it possible to make the hostname a config variable? @danbrown's fix works and doesn't break the repository.
The issue is not directly related to electron-serve. The problem, is related to the new scheme you are using. Most devtools are based on WebSocket connections. Often these connections are intialized using a dynamic url
const url = `${location.protocol}://${location.protocol}`;
Sometimes these urls can be configured. When using webpack you can use the
settings to explicitly configure this url.
module.exports = {
/* ... your webpack config ... */,
devServer: {
host: 'localhost',
port: 3000
}
}
Nevertheless sometimes these urls are not configurable (in Next.js for example). The the only way is to patch your runtime environment. The following code shows an example on how such patch could look like:
File: preload.js
// Use electons webFrame api to execute javascript in the BrowserWindow context.
const { webFrame } = require("electron");
// Patch the global WebSocket constructor to use the correct DevServer url
webFrame.executeJavaScript(`Object.defineProperty(globalThis, 'WebSocket', {
value: new Proxy(WebSocket, {
construct: (Target, [url, protocols]) => {
if (url.endsWith('/_next/webpack-hmr')) {
// Fix the Next.js hmr client url
return new Target("ws://localhost:3000/_next/webpack-hmr", protocols)
} else {
return new Target(url, protocols)
}
}
})
});`);
Disclaimer: Please note that patching the global JavaScript environment can be considered an anti pattern and might cause issues in the future.