Electron使用electron-serve预览静态网站遇ERR_FILE_NOT_FOUND错误求助
(node:12068) electron: Failed to load URL: app://-/ with error: ERR_FILE_NOT_FOUND
(Useelectron --trace-warnings ...to show where the warning was created)
(node:12068) UnhandledPromiseRejectionWarning: Error: ERR_FILE_NOT_FOUND (-6) loading 'app://-/'
at rejectAndCleanup (node:electron/js2c/browser_init:165:7510)
at EventEmitter.failListener (node:electron/js2c/browser_init:165:7723)
at EventEmitter.emit (node:events:527:28)
(node:12068) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag--unhandled-rejections=strict. (rejection id: 1)
[12068:1117/094334.336:ERROR:interface_endpoint_client.cc(689)] Message 3 rejected by interface blink.mojom.Widget
[12068:1117/094334.339:ERROR:interface_endpoint_client.cc(689)] Message 6 rejected by interface blink.mojom.WidgetHost
[12068:1117/094334.339:ERROR:interface_endpoint_client.cc(689)] Message 7 rejected by interface blink.mojom.WidgetHost
main.js 代码
const { app, BrowserWindow, BrowserView, ipcMain, protocol } = require("electron"); const serve = require('electron-serve'); const path = require("path"); const url = require('url'); const isDiv = process.eventNames.NODE_ENV !== "production"; const isMac = process.platform === "darwin"; let loadURL = serve({ directory : path.join(__dirname, "./compressedFolder") }); let mainWindow; // let view; // create main window function createMainWindow() { mainWindow = new BrowserWindow({ icon: path.join(__dirname, "src/img/greenieweb.icns"), width: 1200, height: 800, minHeight: 600, minWidth: 1000, webPreferences: { title: "GreenieWeb", preload: path.join(__dirname, "/src/preload/preload.js"), devTools: true /*Disables Devtools*/, nodeIntegration: true, }, }); // open dev tools if in dev env if (isDiv) { mainWindow.webContents.openDevTools(); } ipcMain.on('app-topreview-loaded', async (event) => { const previewWindow = new BrowserWindow({ parent: mainWindow, show: false, width: 1200, height: 800, minHeight: 600, minWidth: 1000, webPreferences: { title: "Preview", }, }) await loadURL(previewWindow); previewWindow.once('ready-to-show', () => { previewWindow.show() }) }) // load main html file mainWindow.loadFile(path.join(__dirname, "./index.html")); } // App is ready app.whenReady().then(() => { // create the main window createMainWindow(); // Disable menu // Menu.setApplicationMenu(null); // remove mainwindow from memory on close mainWindow.on('closed', () => { mainWindow = null; }); // create window if none is created when app is active app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createMainWindow(); } }); });
renderer.js 代码
let previewBtn = document.getElementById("preview-btn"); const fs = versions.fs; let gFRWRPCounter = 0; let isEmptyDir = true previewBtn.addEventListener("click", () => { if(!isEmptyDir){ removeFolderFromDir() } addFolderToThePlace() window.electronAPI.showWebApp() }) function removeFolderFromDir(){ fs.rmSync('./compressedFolder', { recursive: true, force: true }); fs.mkdir("./compressedFolder", (err) => { if(err){ console.log("Something went wrong") } }) isEmptyDir = true; gFRWRPCounter = 0; } async function addFolderToThePlace(){ if(directoryHandle===undefined){ new Notification(emptyFolderNOTIFICATION_TITLE, { body: emptyFolderNOTIFICATION_BODY, }).show(); return; } for await (const file of getFilesRecursivelyWithRP("", directoryHandle)) { const content = await file.text() await fs.mkdir( "./compressedFolder" + file.relativePath, { recursive: true }, (err) => { if (err) { console.log(err); } else { fs.writeFileSync( "./compressedFolder" + file.relativePath + "/" + file.name, content ); } } ); } isEmptyDir = false } async function* getFilesRecursivelyWithRP(fPath, entry) { if (entry.kind === "file") { const file = await entry.getFile(); if (file !== null) { file.relativePath = fPath; yield file; } } else if (entry.kind === "directory") { let nFPath = ""; if(gFRWRPCounter>0){ nFPath = fPath + "/" + entry.name; }else{ nFPath = fPath gFRWRPCounter++; } for await (const handle of entry.values()) { yield* getFilesRecursivelyWithRP(nFPath, handle); } } }
preload.js 代码
const { contextBridge, ipcRenderer } = require("electron"); const fs = require('fs') // this is just an example contextBridge.exposeInMainWorld("versions", { fs: fs, }); contextBridge.exposeInMainWorld('electronAPI', { showWebApp: () => ipcRenderer.send('app-topreview-loaded') })
我要实现一个静态网站(HTML/CSS/JS)预览功能,流程是上传包含静态文件的文件夹、保存文件,点击按钮后在新窗口预览网站。用electron-serve库实现,但运行时出现上述错误,预览窗口为空白。
代码逻辑是将待预览文件夹上传到项目目录下的compressedFolder,触发app-topreview-loaded事件后打开预览窗口。错误原因应该是初始化serve({ directory : path.join(__dirname, "./compressedFolder") })时该文件夹为空,但把这个函数调用放到ipcMain.on事件处理里会报错,提示必须在app ready前调用。求解决这个问题的方法。
内容的提问来源于stack exchange,提问作者AmineZouh

