Make Electron build
I historically have never liked Electron, and I don't like it now, but unfortunately due to poor browser support, I don't have a choice to ship anything more lightweight if I want to use the Filesystem API as part of the packaged build, which is kind of the point. I guess it's true: "You either die a hero or you live long enough to become the villain." This is an experimental build.
This commit is contained in:
76
electron/main.js
Normal file
76
electron/main.js
Normal file
@@ -0,0 +1,76 @@
|
||||
const { app, BrowserWindow, shell } = require('electron');
|
||||
const http = require('http');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const DIST = path.join(__dirname, 'dist');
|
||||
|
||||
const MIME = {
|
||||
'.html': 'text/html',
|
||||
'.css': 'text/css',
|
||||
'.js': 'application/javascript',
|
||||
'.json': 'application/json',
|
||||
'.wasm': 'application/wasm',
|
||||
'.zip': 'application/zip',
|
||||
'.tgz': 'application/gzip',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.png': 'image/png',
|
||||
'.ico': 'image/x-icon',
|
||||
'.webmanifest': 'application/manifest+json',
|
||||
};
|
||||
|
||||
let server;
|
||||
let win;
|
||||
|
||||
function createWindow() {
|
||||
win = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 900,
|
||||
icon: path.join(DIST, 'favicon', 'favicon-96x96.png'),
|
||||
autoHideMenuBar: true,
|
||||
webPreferences: { contextIsolation: true },
|
||||
});
|
||||
const localOrigin = `http://localhost:${server.address().port}`;
|
||||
|
||||
win.loadURL(localOrigin);
|
||||
win.on('closed', () => { win = null; });
|
||||
|
||||
const isExternal = (url) => {
|
||||
try { return new URL(url).origin !== localOrigin; } catch { return false; }
|
||||
};
|
||||
|
||||
win.webContents.on('will-navigate', (e, url) => {
|
||||
if (isExternal(url)) { e.preventDefault(); shell.openExternal(url); }
|
||||
});
|
||||
win.webContents.setWindowOpenHandler(({ url }) => {
|
||||
if (isExternal(url)) shell.openExternal(url);
|
||||
return { action: 'deny' };
|
||||
});
|
||||
}
|
||||
|
||||
server = http.createServer((req, res) => {
|
||||
const url = new URL(req.url, 'http://localhost');
|
||||
let filePath = path.join(DIST, decodeURIComponent(url.pathname));
|
||||
|
||||
try {
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isDirectory()) filePath = path.join(filePath, 'index.html');
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
fs.statSync(filePath);
|
||||
res.writeHead(200, { 'Content-Type': MIME[path.extname(filePath)] || 'application/octet-stream' });
|
||||
fs.createReadStream(filePath).pipe(res);
|
||||
} catch {
|
||||
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
||||
res.end('Not found');
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(0, '127.0.0.1', () => {
|
||||
app.whenReady().then(createWindow);
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => { app.quit(); });
|
||||
|
||||
app.on('before-quit', () => { server.close(); });
|
||||
Reference in New Issue
Block a user