From 09628c77c7353f756541c4b9b48f5c342f55544f Mon Sep 17 00:00:00 2001 From: iamEvan <47493765+iamEvanYT@users.noreply.github.com> Date: Sun, 8 Dec 2024 14:30:01 +0000 Subject: [PATCH] improve bundling and asset resolution --- backend/package-lock.json | 9 ++++ backend/package.json | 2 + backend/src/index.ts | 3 ++ backend/src/modules/protocols/file.ts | 42 +++++++++++++++++++ backend/webpack.renderer.config.ts | 21 +--------- frontend/components/spotter/elements/icon.tsx | 2 +- frontend/next.config.ts | 8 ++-- 7 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 backend/src/modules/protocols/file.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index bb544ad..019acea 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -24,6 +24,7 @@ "@electron-forge/plugin-fuses": "^7.6.0", "@electron-forge/plugin-webpack": "^7.6.0", "@electron/fuses": "^1.8.0", + "@types/mime-types": "^2.1.4", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "@vercel/webpack-asset-relocator-loader": "^1.7.3", @@ -34,6 +35,7 @@ "eslint": "^8.57.1", "eslint-plugin-import": "^2.31.0", "fork-ts-checker-webpack-plugin": "^7.3.0", + "mime-types": "^2.1.35", "node-loader": "^2.1.0", "style-loader": "^3.3.4", "ts-loader": "^9.5.1", @@ -1538,6 +1540,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mime-types": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz", + "integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", diff --git a/backend/package.json b/backend/package.json index bfa1872..7668fa9 100644 --- a/backend/package.json +++ b/backend/package.json @@ -24,6 +24,7 @@ "@electron-forge/plugin-fuses": "^7.6.0", "@electron-forge/plugin-webpack": "^7.6.0", "@electron/fuses": "^1.8.0", + "@types/mime-types": "^2.1.4", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "@vercel/webpack-asset-relocator-loader": "^1.7.3", @@ -34,6 +35,7 @@ "eslint": "^8.57.1", "eslint-plugin-import": "^2.31.0", "fork-ts-checker-webpack-plugin": "^7.3.0", + "mime-types": "^2.1.35", "node-loader": "^2.1.0", "style-loader": "^3.3.4", "ts-loader": "^9.5.1", diff --git a/backend/src/index.ts b/backend/src/index.ts index 1312c7d..aed53e7 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -2,6 +2,7 @@ import { app } from "electron"; import ipc from "./ipc"; import { createOverlayWindow } from "./windows/overlay"; import { createSpotterWindow } from "./windows/spotter"; +import { registerFileProtocol } from "./modules/protocols/file"; // single instance only const gotLock = app.requestSingleInstanceLock(); @@ -22,6 +23,8 @@ if (!gotLock) { app.on("ready", () => { createSpotterWindow(); createOverlayWindow(); + + registerFileProtocol(); }); app.on("activate", () => { diff --git a/backend/src/modules/protocols/file.ts b/backend/src/modules/protocols/file.ts new file mode 100644 index 0000000..903af7b --- /dev/null +++ b/backend/src/modules/protocols/file.ts @@ -0,0 +1,42 @@ +import { app, protocol } from "electron"; +import * as path from "path"; +import * as fs from "fs"; +import * as mime from "mime-types"; + +export function registerFileProtocol() { + async function respondWithFile(filePath: string) { + const fileContent = await fs.promises.readFile(filePath); + const contentType = mime.lookup(filePath) || "application/octet-stream"; + + return new Response(fileContent, { + status: 200, + headers: { "Content-Type": contentType } + }); + } + + async function handleFileRequest(fileUrl: string): Promise { + const concantatedFilePath = path.join(app.getAppPath(), ".webpack", "renderer", fileUrl); + + if (!fs.existsSync(concantatedFilePath)) { + return respondWithFile(fileUrl); + } + + try { + return respondWithFile(concantatedFilePath); + } catch (error) { + console.error(`Error reading file: ${error.message}`); + return new Response(JSON.stringify({ error: "Internal server error" }), { + status: 500, + headers: { "Content-Type": "application/json" } + }); + } + } + + protocol.handle("file", async (request) => { + const fileUrl = request.url.substring(7); // Remove the "file://" prefix + if (fileUrl.startsWith("/")) { + return handleFileRequest(fileUrl); + } + return respondWithFile(fileUrl); + }); +} diff --git a/backend/webpack.renderer.config.ts b/backend/webpack.renderer.config.ts index c1d647b..c71d8e5 100644 --- a/backend/webpack.renderer.config.ts +++ b/backend/webpack.renderer.config.ts @@ -17,29 +17,13 @@ export const rendererConfig: Configuration = { plugins: [ new CopyPlugin({ patterns: [ - // main (dev) + // main { from: "src/out", to: ".", globOptions: { ignore: ["**/index.html"] } - }, - // spotter window (prod) - { - from: "src/out", - to: "./main_window", - globOptions: { - ignore: ["**/index.html"] - } - }, - // overlay window (prod) - { - from: "src/out", - to: "./overlay_window", - globOptions: { - ignore: ["**/index.html"] - } } ], options: { @@ -50,8 +34,5 @@ export const rendererConfig: Configuration = { ], resolve: { extensions: [".js", ".ts", ".jsx", ".tsx", ".css"] - }, - output: { - publicPath: "./" } }; diff --git a/frontend/components/spotter/elements/icon.tsx b/frontend/components/spotter/elements/icon.tsx index 2783729..b9f6685 100644 --- a/frontend/components/spotter/elements/icon.tsx +++ b/frontend/components/spotter/elements/icon.tsx @@ -46,7 +46,7 @@ export const Icon = React.memo(function Icon({ src, width = 24, height = 24, cla ); } else { // Local asset case - const assetPath = src.startsWith("/") ? src : `./assets/${src}`; + const assetPath = src.startsWith("/") ? src : `/assets/${src}`; return (
Icon diff --git a/frontend/next.config.ts b/frontend/next.config.ts index 8108793..2c86953 100644 --- a/frontend/next.config.ts +++ b/frontend/next.config.ts @@ -1,6 +1,6 @@ import type { NextConfig } from "next"; -const isDev = process.env.NODE_ENV === "development"; +// const isDev = process.env.NODE_ENV === "development"; const nextConfig: NextConfig = { output: "export", @@ -12,8 +12,8 @@ const nextConfig: NextConfig = { } }; -if (!isDev) { - nextConfig.assetPrefix = "."; -} +// if (!isDev) { +// nextConfig.assetPrefix = "."; +// } export default nextConfig;