refactor(electron): improve build process and configuration
- Enhance electron build configuration with proper asset handling - Add comprehensive logging and error tracking - Implement CSP headers for security - Fix module exports for logger compatibility - Update TypeScript and Vite configs for better build support - Improve development workflow with better dev tools integration
This commit is contained in:
13
package.json
13
package.json
@@ -22,11 +22,11 @@
|
||||
"check:ios-device": "xcrun xctrace list devices 2>&1 | grep -w 'Booted' || (echo 'No iOS simulator running' && exit 1)",
|
||||
"clean:electron": "rimraf dist-electron",
|
||||
"build:pywebview": "vite build --config vite.config.pywebview.mts",
|
||||
"build:electron": "npm run clean:electron && vite build --config vite.config.electron.mts && node scripts/build-electron.js",
|
||||
"build:electron": "npm run clean:electron && tsc -p tsconfig.electron.json && vite build --config vite.config.electron.mts && node scripts/build-electron.js",
|
||||
"build:capacitor": "vite build --mode capacitor --config vite.config.capacitor.mts",
|
||||
"build:web": "vite build --config vite.config.web.mts",
|
||||
"electron:dev": "npm run build && electron dist-electron",
|
||||
"electron:start": "electron dist-electron",
|
||||
"electron:dev": "npm run build && electron .",
|
||||
"electron:start": "electron .",
|
||||
"clean:android": "adb uninstall app.timesafari.app || true",
|
||||
"build:android": "npm run clean:android && rm -rf dist && npm run build:web && npm run build:capacitor && cd android && ./gradlew clean && ./gradlew assembleDebug && cd .. && npx cap sync android && npx capacitor-assets generate --android && npx cap open android",
|
||||
"electron:build-linux": "npm run build:electron && electron-builder --linux AppImage",
|
||||
@@ -169,13 +169,12 @@
|
||||
},
|
||||
"files": [
|
||||
"dist-electron/**/*",
|
||||
"src/electron/**/*",
|
||||
"main.js"
|
||||
"dist/**/*"
|
||||
],
|
||||
"extraResources": [
|
||||
{
|
||||
"from": "dist-electron",
|
||||
"to": "."
|
||||
"from": "dist",
|
||||
"to": "www"
|
||||
}
|
||||
],
|
||||
"linux": {
|
||||
|
||||
@@ -1,98 +1,243 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
console.log('Starting electron build process...');
|
||||
|
||||
// Create dist directory if it doesn't exist
|
||||
const distElectronDir = path.resolve(__dirname, '../dist-electron');
|
||||
await fs.ensureDir(distElectronDir);
|
||||
|
||||
// Copy web files
|
||||
const wwwDir = path.join(distElectronDir, 'www');
|
||||
await fs.ensureDir(wwwDir);
|
||||
await fs.copy('dist', wwwDir);
|
||||
const webDistPath = path.join(__dirname, '..', 'dist');
|
||||
const electronDistPath = path.join(__dirname, '..', 'dist-electron');
|
||||
const wwwPath = path.join(electronDistPath, 'www');
|
||||
|
||||
// Copy and fix index.html
|
||||
const indexPath = path.join(wwwDir, 'index.html');
|
||||
let indexContent = await fs.readFile(indexPath, 'utf8');
|
||||
// Create www directory if it doesn't exist
|
||||
if (!fs.existsSync(wwwPath)) {
|
||||
fs.mkdirSync(wwwPath, { recursive: true });
|
||||
}
|
||||
|
||||
// More comprehensive path fixing
|
||||
// Copy web files to www directory
|
||||
fs.cpSync(webDistPath, wwwPath, { recursive: true });
|
||||
|
||||
// Fix asset paths in index.html
|
||||
const indexPath = path.join(wwwPath, 'index.html');
|
||||
let indexContent = fs.readFileSync(indexPath, 'utf8');
|
||||
|
||||
// Fix asset paths
|
||||
indexContent = indexContent
|
||||
// Fix absolute paths to be relative
|
||||
.replace(/src="\//g, 'src="\./')
|
||||
.replace(/href="\//g, 'href="\./')
|
||||
// Fix modulepreload paths
|
||||
.replace(/<link [^>]*rel="modulepreload"[^>]*href="\/assets\//g, '<link rel="modulepreload" as="script" crossorigin="" href="./assets/')
|
||||
.replace(/<link [^>]*rel="modulepreload"[^>]*href="\.\/assets\//g, '<link rel="modulepreload" as="script" crossorigin="" href="./assets/')
|
||||
// Fix stylesheet paths
|
||||
.replace(/<link [^>]*rel="stylesheet"[^>]*href="\/assets\//g, '<link rel="stylesheet" crossorigin="" href="./assets/')
|
||||
.replace(/<link [^>]*rel="stylesheet"[^>]*href="\.\/assets\//g, '<link rel="stylesheet" crossorigin="" href="./assets/')
|
||||
// Fix script paths
|
||||
.replace(/src="\/assets\//g, 'src="./assets/')
|
||||
.replace(/src="\.\/assets\//g, 'src="./assets/')
|
||||
// Fix any remaining asset paths
|
||||
.replace(/(['"]\/?)(assets\/)/g, '"./assets/');
|
||||
.replace(/\/assets\//g, './assets/')
|
||||
.replace(/href="\//g, 'href="./')
|
||||
.replace(/src="\//g, 'src="./');
|
||||
|
||||
// Debug output
|
||||
fs.writeFileSync(indexPath, indexContent);
|
||||
|
||||
// Check for remaining /assets/ paths
|
||||
console.log('After path fixing, checking for remaining /assets/ paths:', indexContent.includes('/assets/'));
|
||||
console.log('Sample of fixed content:', indexContent.slice(0, 500));
|
||||
|
||||
await fs.writeFile(indexPath, indexContent);
|
||||
console.log('Sample of fixed content:', indexContent.substring(0, 500));
|
||||
|
||||
console.log('Copied and fixed web files in:', wwwDir);
|
||||
console.log('Copied and fixed web files in:', wwwPath);
|
||||
|
||||
// Copy main process files
|
||||
console.log('Copying main process files...');
|
||||
const mainProcessFiles = [
|
||||
['src/electron/main.js', 'main.js'],
|
||||
['src/electron/preload.js', 'preload.js']
|
||||
];
|
||||
|
||||
for (const [src, dest] of mainProcessFiles) {
|
||||
const destPath = path.join(distElectronDir, dest);
|
||||
console.log(`Copying ${src} to ${destPath}`);
|
||||
await fs.copy(src, destPath);
|
||||
}
|
||||
// Create the main process file with inlined logger
|
||||
const mainContent = `const { app, BrowserWindow } = require("electron");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
// Create package.json for production
|
||||
const devPackageJson = require('../package.json');
|
||||
const prodPackageJson = {
|
||||
name: devPackageJson.name,
|
||||
version: devPackageJson.version,
|
||||
description: devPackageJson.description,
|
||||
author: devPackageJson.author,
|
||||
main: 'main.js',
|
||||
private: true,
|
||||
};
|
||||
// Inline logger implementation
|
||||
const logger = {
|
||||
log: (...args) => console.log(...args),
|
||||
error: (...args) => console.error(...args),
|
||||
info: (...args) => console.info(...args),
|
||||
warn: (...args) => console.warn(...args),
|
||||
debug: (...args) => console.debug(...args),
|
||||
};
|
||||
|
||||
await fs.writeJson(
|
||||
path.join(distElectronDir, 'package.json'),
|
||||
prodPackageJson,
|
||||
{ spaces: 2 }
|
||||
);
|
||||
// Check if running in dev mode
|
||||
const isDev = process.argv.includes("--inspect");
|
||||
|
||||
// Verify the build
|
||||
console.log('\nVerifying build structure:');
|
||||
const files = await fs.readdir(distElectronDir);
|
||||
console.log('Files in dist-electron:', files);
|
||||
function createWindow() {
|
||||
// Add before createWindow function
|
||||
const preloadPath = path.join(__dirname, "preload.js");
|
||||
logger.log("Checking preload path:", preloadPath);
|
||||
logger.log("Preload exists:", fs.existsSync(preloadPath));
|
||||
|
||||
if (!files.includes('main.js')) {
|
||||
throw new Error('main.js not found in build directory');
|
||||
}
|
||||
if (!files.includes('preload.js')) {
|
||||
throw new Error('preload.js not found in build directory');
|
||||
}
|
||||
if (!files.includes('package.json')) {
|
||||
throw new Error('package.json not found in build directory');
|
||||
}
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
webSecurity: true,
|
||||
allowRunningInsecureContent: false,
|
||||
preload: path.join(__dirname, "preload.js"),
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Build completed successfully!');
|
||||
} catch (error) {
|
||||
console.error('Build failed:', error);
|
||||
process.exit(1);
|
||||
// Always open DevTools for now
|
||||
mainWindow.webContents.openDevTools();
|
||||
|
||||
// Intercept requests to fix asset paths
|
||||
mainWindow.webContents.session.webRequest.onBeforeRequest(
|
||||
{
|
||||
urls: [
|
||||
"file://*/*/assets/*",
|
||||
"file://*/assets/*",
|
||||
"file:///assets/*", // Catch absolute paths
|
||||
"<all_urls>", // Catch all URLs as a fallback
|
||||
],
|
||||
},
|
||||
(details, callback) => {
|
||||
let url = details.url;
|
||||
|
||||
// Handle paths that don't start with file://
|
||||
if (!url.startsWith("file://") && url.includes("/assets/")) {
|
||||
url = \`file://\${path.join(__dirname, "www", url)}\`;
|
||||
}
|
||||
|
||||
// Handle absolute paths starting with /assets/
|
||||
if (url.includes("/assets/") && !url.includes("/www/assets/")) {
|
||||
const baseDir = url.includes("dist-electron")
|
||||
? url.substring(
|
||||
0,
|
||||
url.indexOf("/dist-electron") + "/dist-electron".length,
|
||||
)
|
||||
: \`file://\${__dirname}\`;
|
||||
const assetPath = url.split("/assets/")[1];
|
||||
const newUrl = \`\${baseDir}/www/assets/\${assetPath}\`;
|
||||
callback({ redirectURL: newUrl });
|
||||
return;
|
||||
}
|
||||
|
||||
callback({}); // No redirect for other URLs
|
||||
},
|
||||
);
|
||||
|
||||
if (isDev) {
|
||||
// Debug info
|
||||
logger.log("Debug Info:");
|
||||
logger.log("Running in dev mode:", isDev);
|
||||
logger.log("App is packaged:", app.isPackaged);
|
||||
logger.log("Process resource path:", process.resourcesPath);
|
||||
logger.log("App path:", app.getAppPath());
|
||||
logger.log("__dirname:", __dirname);
|
||||
logger.log("process.cwd():", process.cwd());
|
||||
}
|
||||
|
||||
const indexPath = path.join(__dirname, "www", "index.html");
|
||||
|
||||
if (isDev) {
|
||||
logger.log("Loading index from:", indexPath);
|
||||
logger.log("www path:", path.join(__dirname, "www"));
|
||||
logger.log("www assets path:", path.join(__dirname, "www", "assets"));
|
||||
}
|
||||
|
||||
if (!fs.existsSync(indexPath)) {
|
||||
logger.error(\`Index file not found at: \${indexPath}\`);
|
||||
throw new Error("Index file not found");
|
||||
}
|
||||
|
||||
// Add CSP headers to allow API connections, Google Fonts, and zxing-wasm
|
||||
mainWindow.webContents.session.webRequest.onHeadersReceived(
|
||||
(details, callback) => {
|
||||
callback({
|
||||
responseHeaders: {
|
||||
...details.responseHeaders,
|
||||
"Content-Security-Policy": [
|
||||
"default-src 'self';" +
|
||||
"connect-src 'self' https://api.endorser.ch https://*.timesafari.app https://*.jsdelivr.net;" +
|
||||
"img-src 'self' data: https: blob:;" +
|
||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.jsdelivr.net;" +
|
||||
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;" +
|
||||
"font-src 'self' data: https://fonts.gstatic.com;" +
|
||||
"style-src-elem 'self' 'unsafe-inline' https://fonts.googleapis.com;" +
|
||||
"worker-src 'self' blob:;",
|
||||
],
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Load the index.html
|
||||
mainWindow
|
||||
.loadFile(indexPath)
|
||||
.then(() => {
|
||||
logger.log("Successfully loaded index.html");
|
||||
if (isDev) {
|
||||
mainWindow.webContents.openDevTools();
|
||||
logger.log("DevTools opened - running in dev mode");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error("Failed to load index.html:", err);
|
||||
logger.error("Attempted path:", indexPath);
|
||||
});
|
||||
|
||||
// Listen for console messages from the renderer
|
||||
mainWindow.webContents.on("console-message", (_event, _level, message) => {
|
||||
logger.log("Renderer Console:", message);
|
||||
});
|
||||
|
||||
// Add right after creating the BrowserWindow
|
||||
mainWindow.webContents.on(
|
||||
"did-fail-load",
|
||||
(_event, errorCode, errorDescription) => {
|
||||
logger.error("Page failed to load:", errorCode, errorDescription);
|
||||
},
|
||||
);
|
||||
|
||||
mainWindow.webContents.on("preload-error", (_event, preloadPath, error) => {
|
||||
logger.error("Preload script error:", preloadPath, error);
|
||||
});
|
||||
|
||||
mainWindow.webContents.on(
|
||||
"console-message",
|
||||
(_event, _level, message, line, sourceId) => {
|
||||
logger.log("Renderer Console:", line, sourceId, message);
|
||||
},
|
||||
);
|
||||
|
||||
// Enable remote debugging when in dev mode
|
||||
if (isDev) {
|
||||
mainWindow.webContents.openDevTools();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
// Handle app ready
|
||||
app.whenReady().then(createWindow);
|
||||
|
||||
// Handle all windows closed
|
||||
app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin") {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on("activate", () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle any errors
|
||||
process.on("uncaughtException", (error) => {
|
||||
logger.error("Uncaught Exception:", error);
|
||||
});
|
||||
`;
|
||||
|
||||
// Write the main process file
|
||||
const mainDest = path.join(electronDistPath, 'main.js');
|
||||
fs.writeFileSync(mainDest, mainContent);
|
||||
|
||||
// Copy preload script if it exists
|
||||
const preloadSrc = path.join(__dirname, '..', 'src', 'electron', 'preload.js');
|
||||
const preloadDest = path.join(electronDistPath, 'preload.js');
|
||||
if (fs.existsSync(preloadSrc)) {
|
||||
console.log(`Copying ${preloadSrc} to ${preloadDest}`);
|
||||
fs.copyFileSync(preloadSrc, preloadDest);
|
||||
}
|
||||
|
||||
// Verify build structure
|
||||
console.log('\nVerifying build structure:');
|
||||
console.log('Files in dist-electron:', fs.readdirSync(electronDistPath));
|
||||
|
||||
console.log('Build completed successfully!');
|
||||
183
src/electron/main.ts
Normal file
183
src/electron/main.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
import { app, BrowserWindow } from "electron";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
// Simple logger implementation
|
||||
const logger = {
|
||||
log: (...args: unknown[]) => console.log(...args),
|
||||
error: (...args: unknown[]) => console.error(...args),
|
||||
info: (...args: unknown[]) => console.info(...args),
|
||||
warn: (...args: unknown[]) => console.warn(...args),
|
||||
debug: (...args: unknown[]) => console.debug(...args),
|
||||
};
|
||||
|
||||
// Check if running in dev mode
|
||||
const isDev = process.argv.includes("--inspect");
|
||||
|
||||
function createWindow(): void {
|
||||
// Add before createWindow function
|
||||
const preloadPath = path.join(__dirname, "preload.js");
|
||||
logger.log("Checking preload path:", preloadPath);
|
||||
logger.log("Preload exists:", fs.existsSync(preloadPath));
|
||||
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
webSecurity: true,
|
||||
allowRunningInsecureContent: false,
|
||||
preload: path.join(__dirname, "preload.js"),
|
||||
},
|
||||
});
|
||||
|
||||
// Always open DevTools for now
|
||||
mainWindow.webContents.openDevTools();
|
||||
|
||||
// Intercept requests to fix asset paths
|
||||
mainWindow.webContents.session.webRequest.onBeforeRequest(
|
||||
{
|
||||
urls: [
|
||||
"file://*/*/assets/*",
|
||||
"file://*/assets/*",
|
||||
"file:///assets/*", // Catch absolute paths
|
||||
"<all_urls>", // Catch all URLs as a fallback
|
||||
],
|
||||
},
|
||||
(details, callback) => {
|
||||
let url = details.url;
|
||||
|
||||
// Handle paths that don't start with file://
|
||||
if (!url.startsWith("file://") && url.includes("/assets/")) {
|
||||
url = `file://${path.join(__dirname, "www", url)}`;
|
||||
}
|
||||
|
||||
// Handle absolute paths starting with /assets/
|
||||
if (url.includes("/assets/") && !url.includes("/www/assets/")) {
|
||||
const baseDir = url.includes("dist-electron")
|
||||
? url.substring(
|
||||
0,
|
||||
url.indexOf("/dist-electron") + "/dist-electron".length,
|
||||
)
|
||||
: `file://${__dirname}`;
|
||||
const assetPath = url.split("/assets/")[1];
|
||||
const newUrl = `${baseDir}/www/assets/${assetPath}`;
|
||||
callback({ redirectURL: newUrl });
|
||||
return;
|
||||
}
|
||||
|
||||
callback({}); // No redirect for other URLs
|
||||
},
|
||||
);
|
||||
|
||||
if (isDev) {
|
||||
// Debug info
|
||||
logger.log("Debug Info:");
|
||||
logger.log("Running in dev mode:", isDev);
|
||||
logger.log("App is packaged:", app.isPackaged);
|
||||
logger.log("Process resource path:", process.resourcesPath);
|
||||
logger.log("App path:", app.getAppPath());
|
||||
logger.log("__dirname:", __dirname);
|
||||
logger.log("process.cwd():", process.cwd());
|
||||
}
|
||||
|
||||
const indexPath = path.join(__dirname, "www", "index.html");
|
||||
|
||||
if (isDev) {
|
||||
logger.log("Loading index from:", indexPath);
|
||||
logger.log("www path:", path.join(__dirname, "www"));
|
||||
logger.log("www assets path:", path.join(__dirname, "www", "assets"));
|
||||
}
|
||||
|
||||
if (!fs.existsSync(indexPath)) {
|
||||
logger.error(`Index file not found at: ${indexPath}`);
|
||||
throw new Error("Index file not found");
|
||||
}
|
||||
|
||||
// Add CSP headers to allow API connections
|
||||
mainWindow.webContents.session.webRequest.onHeadersReceived(
|
||||
(details, callback) => {
|
||||
callback({
|
||||
responseHeaders: {
|
||||
...details.responseHeaders,
|
||||
"Content-Security-Policy": [
|
||||
"default-src 'self';" +
|
||||
"connect-src 'self' https://api.endorser.ch https://*.timesafari.app;" +
|
||||
"img-src 'self' data: https: blob:;" +
|
||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval';" +
|
||||
"style-src 'self' 'unsafe-inline';" +
|
||||
"font-src 'self' data:;",
|
||||
],
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Load the index.html
|
||||
mainWindow
|
||||
.loadFile(indexPath)
|
||||
.then(() => {
|
||||
logger.log("Successfully loaded index.html");
|
||||
if (isDev) {
|
||||
mainWindow.webContents.openDevTools();
|
||||
logger.log("DevTools opened - running in dev mode");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error("Failed to load index.html:", err);
|
||||
logger.error("Attempted path:", indexPath);
|
||||
});
|
||||
|
||||
// Listen for console messages from the renderer
|
||||
mainWindow.webContents.on("console-message", (_event, _level, message) => {
|
||||
logger.log("Renderer Console:", message);
|
||||
});
|
||||
|
||||
// Add right after creating the BrowserWindow
|
||||
mainWindow.webContents.on(
|
||||
"did-fail-load",
|
||||
(_event, errorCode, errorDescription) => {
|
||||
logger.error("Page failed to load:", errorCode, errorDescription);
|
||||
},
|
||||
);
|
||||
|
||||
mainWindow.webContents.on("preload-error", (_event, preloadPath, error) => {
|
||||
logger.error("Preload script error:", preloadPath, error);
|
||||
});
|
||||
|
||||
mainWindow.webContents.on(
|
||||
"console-message",
|
||||
(_event, _level, message, line, sourceId) => {
|
||||
logger.log("Renderer Console:", line, sourceId, message);
|
||||
},
|
||||
);
|
||||
|
||||
// Enable remote debugging when in dev mode
|
||||
if (isDev) {
|
||||
mainWindow.webContents.openDevTools();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle app ready
|
||||
app.whenReady().then(createWindow);
|
||||
|
||||
// Handle all windows closed
|
||||
app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin") {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on("activate", () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle any errors
|
||||
process.on("uncaughtException", (error) => {
|
||||
logger.error("Uncaught Exception:", error);
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import { logToDb } from "../db";
|
||||
function safeStringify(obj: unknown) {
|
||||
const seen = new WeakSet();
|
||||
|
||||
return JSON.stringify(obj, (key, value) => {
|
||||
return JSON.stringify(obj, (_key, value) => {
|
||||
if (typeof value === "object" && value !== null) {
|
||||
if (seen.has(value)) {
|
||||
return "[Circular]";
|
||||
@@ -69,3 +69,11 @@ export const logger = {
|
||||
logToDb(message + argsString);
|
||||
},
|
||||
};
|
||||
|
||||
// Add CommonJS export for Electron
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = { logger };
|
||||
}
|
||||
|
||||
// Add default export for ESM
|
||||
export default { logger };
|
||||
|
||||
26
tsconfig.electron.json
Normal file
26
tsconfig.electron.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"target": "ES2020",
|
||||
"outDir": "dist-electron",
|
||||
"rootDir": "src",
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"allowJs": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"types": ["vite/client"],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"src/electron/**/*.ts",
|
||||
"src/utils/**/*.ts",
|
||||
"src/constants/**/*.ts"
|
||||
]
|
||||
}
|
||||
@@ -4,7 +4,9 @@
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["vite.config.*"]
|
||||
}
|
||||
@@ -1,11 +1,58 @@
|
||||
import { defineConfig, mergeConfig } from "vite";
|
||||
import { createBuildConfig } from "./vite.config.common.mts";
|
||||
import path from 'path';
|
||||
|
||||
export default defineConfig(async () => {
|
||||
const baseConfig = await createBuildConfig('electron');
|
||||
|
||||
return mergeConfig(baseConfig, {
|
||||
plugins: [{
|
||||
build: {
|
||||
outDir: 'dist-electron',
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: path.resolve(__dirname, 'src/electron/main.ts'),
|
||||
preload: path.resolve(__dirname, 'src/electron/preload.js'),
|
||||
},
|
||||
external: ['electron'],
|
||||
output: {
|
||||
format: 'cjs',
|
||||
entryFileNames: '[name].js',
|
||||
assetFileNames: 'assets/[name].[ext]',
|
||||
},
|
||||
},
|
||||
target: 'node18',
|
||||
minify: false,
|
||||
sourcemap: true,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
},
|
||||
},
|
||||
optimizeDeps: {
|
||||
include: ['@/utils/logger']
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
name: 'typescript-transform',
|
||||
transform(code: string, id: string) {
|
||||
if (id.endsWith('main.ts')) {
|
||||
// Replace the logger import with inline logger
|
||||
return code.replace(
|
||||
/import\s*{\s*logger\s*}\s*from\s*['"]@\/utils\/logger['"];?/,
|
||||
`const logger = {
|
||||
log: (...args) => console.log(...args),
|
||||
error: (...args) => console.error(...args),
|
||||
info: (...args) => console.info(...args),
|
||||
warn: (...args) => console.warn(...args),
|
||||
debug: (...args) => console.debug(...args),
|
||||
};`
|
||||
);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'remove-sw-imports',
|
||||
transform(code: string, id: string) {
|
||||
if (
|
||||
@@ -24,6 +71,12 @@ export default defineConfig(async () => {
|
||||
};
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
],
|
||||
ssr: {
|
||||
noExternal: ['@/utils/logger']
|
||||
},
|
||||
base: './',
|
||||
publicDir: 'public',
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user