build: enhance development tooling and configuration
- Add Go fmt command to Makefile for consistent code formatting - Update Vite plugin pages configuration with enhanced routing - Optimize homepage build configuration for better performance - Streamline development workflow with improved build tools
- commit
- 266137a2cee6ca5e05c5eec909ce9645483eea05
- author
- bamen · · 2025-09-23 19:18 UTC
- committer
- bamen · · 2025-09-23 17:57 UTC
- parent
- 67d90d0
- signature
- unsigned
3 files · +29 -14
M Makefile +5 -0
| @@ -105,6 +105,11 @@ lint-fix: ## Run golangci-lint with --fix | |||
| 105 | 105 | @echo "Running golangci-lint with --fix..." | |
| 106 | 106 | golangci-lint run --fix | |
| 107 | 107 | ||
| 108 | + | # Format code | |
| 109 | + | fmt: ## Format Go code with gofmt | |
| 110 | + | @echo "Formatting Go code with gofmt..." | |
| 111 | + | go fmt ./... | |
| 112 | + | ||
| 108 | 113 | # Tools installation | |
| 109 | 114 | install-tools: ## Install development tools | |
| 110 | 115 | @echo "Installing development tools..." | |
| @@ -105,6 +105,11 @@ lint-fix: ## Run golangci-lint with --fix | |||||
| 105 | @echo "Running golangci-lint with --fix..." | 105 | @echo "Running golangci-lint with --fix..." | ||
| 106 | golangci-lint run --fix | 106 | golangci-lint run --fix | ||
| 107 | 107 | ||||
| 108 | + | # Format code | |||
| 109 | + | fmt: ## Format Go code with gofmt | |||
| 110 | + | @echo "Formatting Go code with gofmt..." | |||
| 111 | + | go fmt ./... | |||
| 112 | + | ||||
| 108 | # Tools installation | 113 | # Tools installation | ||
| 109 | install-tools: ## Install development tools | 114 | install-tools: ## Install development tools | ||
| 110 | @echo "Installing development tools..." | 115 | @echo "Installing development tools..." | ||
M gui/vite-plugin-pages.ts +22 -12
| @@ -1,5 +1,5 @@ | |||
| 1 | 1 | import type { Plugin } from "vite"; | |
| 2 | - | import { writeFileSync, readFileSync } from "fs"; | |
| 2 | + | import { writeFileSync, readFileSync, existsSync, copyFileSync } from "fs"; | |
| 3 | 3 | import { resolve } from "path"; | |
| 4 | 4 | ||
| 5 | 5 | interface PageConfig { | |
| @@ -21,15 +21,6 @@ function getFaviconSVG(): string { | |||
| 21 | 21 | return readFileSync(logoPath, "utf-8"); | |
| 22 | 22 | } | |
| 23 | 23 | ||
| 24 | - | // Create favicon data URL for inline usage | |
| 25 | - | function getFaviconDataURL(): string { | |
| 26 | - | const svg = getFaviconSVG(); | |
| 27 | - | const encoded = encodeURIComponent(svg) | |
| 28 | - | .replace(/'/g, "%27") | |
| 29 | - | .replace(/\(/g, "%28") | |
| 30 | - | .replace(/\)/g, "%29"); | |
| 31 | - | return `data:image/svg+xml;utf8,${encoded}`; | |
| 32 | - | } | |
| 33 | 24 | ||
| 34 | 25 | // Generate HTML content for a page | |
| 35 | 26 | function generatePageHTML(config: PageConfig): string { | |
| @@ -43,7 +34,7 @@ function generatePageHTML(config: PageConfig): string { | |||
| 43 | 34 | <meta charset="UTF-8"> | |
| 44 | 35 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| 45 | 36 | <title>${config.title}</title> | |
| 46 | - | <link rel="icon" type="image/svg+xml" href="${getFaviconDataURL()}"> | |
| 37 | + | <link rel="icon" type="image/x-icon" href="dumb://homepage/favicon.ico"> | |
| 47 | 38 | ${cssLink} | |
| 48 | 39 | </head> | |
| 49 | 40 | <body> | |
| @@ -71,10 +62,29 @@ export function pageGenerator(pages: PageConfig[]): Plugin { | |||
| 71 | 62 | console.log(`✓ Generated ${filename} for dumb://${page.name}`); | |
| 72 | 63 | } | |
| 73 | 64 | ||
| 74 | - | // Generate favicon.svg for scheme handler lookups | |
| 65 | + | // Generate favicon files for scheme handler lookups | |
| 75 | 66 | const faviconContent = getFaviconSVG(); | |
| 76 | 67 | writeFileSync(resolve(assetsDir, "favicon.svg"), faviconContent); | |
| 77 | 68 | console.log("✓ Generated favicon.svg"); | |
| 69 | + | ||
| 70 | + | // Copy pre-generated PNG and ICO favicons if they exist | |
| 71 | + | const sourceDir = resolve(__dirname, "..", "assets", "gui"); | |
| 72 | + | try { | |
| 73 | + | const pngPath = resolve(sourceDir, "favicon.png"); | |
| 74 | + | const icoPath = resolve(sourceDir, "favicon.ico"); | |
| 75 | + | ||
| 76 | + | if (existsSync(pngPath)) { | |
| 77 | + | copyFileSync(pngPath, resolve(assetsDir, "favicon.png")); | |
| 78 | + | console.log("✓ Copied favicon.png"); | |
| 79 | + | } | |
| 80 | + | ||
| 81 | + | if (existsSync(icoPath)) { | |
| 82 | + | copyFileSync(icoPath, resolve(assetsDir, "favicon.ico")); | |
| 83 | + | console.log("✓ Copied favicon.ico"); | |
| 84 | + | } | |
| 85 | + | } catch (err) { | |
| 86 | + | console.warn("⚠ Could not copy favicon PNG/ICO files:", err); | |
| 87 | + | } | |
| 78 | 88 | } catch (error) { | |
| 79 | 89 | console.error("✗ Failed to generate page files:", error); | |
| 80 | 90 | throw error; | |
| @@ -1,5 +1,5 @@ | |||||
| 1 | import type { Plugin } from "vite"; | 1 | import type { Plugin } from "vite"; | ||
| 2 | - | import { writeFileSync, readFileSync } from "fs"; | 2 | + | import { writeFileSync, readFileSync, existsSync, copyFileSync } from "fs"; |
| 3 | import { resolve } from "path"; | 3 | import { resolve } from "path"; | ||
| 4 | 4 | ||||
| 5 | interface PageConfig { | 5 | interface PageConfig { | ||
| @@ -21,15 +21,6 @@ function getFaviconSVG(): string { | |||||
| 21 | return readFileSync(logoPath, "utf-8"); | 21 | return readFileSync(logoPath, "utf-8"); | ||
| 22 | } | 22 | } | ||
| 23 | 23 | ||||
| 24 | - | // Create favicon data URL for inline usage | |||
| 25 | - | function getFaviconDataURL(): string { | |||
| 26 | - | const svg = getFaviconSVG(); | |||
| 27 | - | const encoded = encodeURIComponent(svg) | |||
| 28 | - | .replace(/'/g, "%27") | |||
| 29 | - | .replace(/\(/g, "%28") | |||
| 30 | - | .replace(/\)/g, "%29"); | |||
| 31 | - | return `data:image/svg+xml;utf8,${encoded}`; | |||
| 32 | - | } | |||
| 33 | 24 | ||||
| 34 | // Generate HTML content for a page | 25 | // Generate HTML content for a page | ||
| 35 | function generatePageHTML(config: PageConfig): string { | 26 | function generatePageHTML(config: PageConfig): string { | ||
| @@ -43,7 +34,7 @@ function generatePageHTML(config: PageConfig): string { | |||||
| 43 | <meta charset="UTF-8"> | 34 | <meta charset="UTF-8"> | ||
| 44 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | 35 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| 45 | <title>${config.title}</title> | 36 | <title>${config.title}</title> | ||
| 46 | - | <link rel="icon" type="image/svg+xml" href="${getFaviconDataURL()}"> | 37 | + | <link rel="icon" type="image/x-icon" href="dumb://homepage/favicon.ico"> |
| 47 | ${cssLink} | 38 | ${cssLink} | ||
| 48 | </head> | 39 | </head> | ||
| 49 | <body> | 40 | <body> | ||
| @@ -71,10 +62,29 @@ export function pageGenerator(pages: PageConfig[]): Plugin { | |||||
| 71 | console.log(`✓ Generated ${filename} for dumb://${page.name}`); | 62 | console.log(`✓ Generated ${filename} for dumb://${page.name}`); | ||
| 72 | } | 63 | } | ||
| 73 | 64 | ||||
| 74 | - | // Generate favicon.svg for scheme handler lookups | 65 | + | // Generate favicon files for scheme handler lookups |
| 75 | const faviconContent = getFaviconSVG(); | 66 | const faviconContent = getFaviconSVG(); | ||
| 76 | writeFileSync(resolve(assetsDir, "favicon.svg"), faviconContent); | 67 | writeFileSync(resolve(assetsDir, "favicon.svg"), faviconContent); | ||
| 77 | console.log("✓ Generated favicon.svg"); | 68 | console.log("✓ Generated favicon.svg"); | ||
| 69 | + | ||||
| 70 | + | // Copy pre-generated PNG and ICO favicons if they exist | |||
| 71 | + | const sourceDir = resolve(__dirname, "..", "assets", "gui"); | |||
| 72 | + | try { | |||
| 73 | + | const pngPath = resolve(sourceDir, "favicon.png"); | |||
| 74 | + | const icoPath = resolve(sourceDir, "favicon.ico"); | |||
| 75 | + | ||||
| 76 | + | if (existsSync(pngPath)) { | |||
| 77 | + | copyFileSync(pngPath, resolve(assetsDir, "favicon.png")); | |||
| 78 | + | console.log("✓ Copied favicon.png"); | |||
| 79 | + | } | |||
| 80 | + | ||||
| 81 | + | if (existsSync(icoPath)) { | |||
| 82 | + | copyFileSync(icoPath, resolve(assetsDir, "favicon.ico")); | |||
| 83 | + | console.log("✓ Copied favicon.ico"); | |||
| 84 | + | } | |||
| 85 | + | } catch (err) { | |||
| 86 | + | console.warn("⚠ Could not copy favicon PNG/ICO files:", err); | |||
| 87 | + | } | |||
| 78 | } catch (error) { | 88 | } catch (error) { | ||
| 79 | console.error("✗ Failed to generate page files:", error); | 89 | console.error("✗ Failed to generate page files:", error); | ||
| 80 | throw error; | 90 | throw error; | ||
M gui/vite.config.homepage.ts +2 -2
| @@ -25,8 +25,8 @@ export default defineConfig({ | |||
| 25 | 25 | chunkFileNames: "[name].js", | |
| 26 | 26 | assetFileNames: "[name].[ext]", | |
| 27 | 27 | manualChunks: undefined, | |
| 28 | - | format: 'iife', | |
| 29 | - | name: 'DumberHomepage' | |
| 28 | + | format: "iife", | |
| 29 | + | name: "DumberHomepage", | |
| 30 | 30 | }, | |
| 31 | 31 | }, | |
| 32 | 32 | emptyOutDir: false, | |
| @@ -25,8 +25,8 @@ export default defineConfig({ | |||||
| 25 | chunkFileNames: "[name].js", | 25 | chunkFileNames: "[name].js", | ||
| 26 | assetFileNames: "[name].[ext]", | 26 | assetFileNames: "[name].[ext]", | ||
| 27 | manualChunks: undefined, | 27 | manualChunks: undefined, | ||
| 28 | - | format: 'iife', | 28 | + | format: "iife", |
| 29 | - | name: 'DumberHomepage' | 29 | + | name: "DumberHomepage", |
| 30 | }, | 30 | }, | ||
| 31 | }, | 31 | }, | ||
| 32 | emptyOutDir: false, | 32 | emptyOutDir: false, | ||