From 2e290ad488f00d460b20a71bd0078d904f5e2f1b Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Fri, 18 Jul 2025 09:40:12 +0000 Subject: [PATCH] grr: experimental diagnosis and fix for build:web:serve --- scripts/build-web.sh | 14 ++++- src/registerSQLWorker.js | 75 +++++++++++++++++++++++++ src/test/EntityGridFunctionPropTest.vue | 2 +- src/views/ContactAmountsView.vue | 4 +- src/views/ContactsView.vue | 2 +- src/views/ImportDerivedAccountView.vue | 4 +- vite.config.common.mts | 58 ++++++++++++++++++- vite.config.optimized.mts | 18 +++++- vite.config.web.mts | 17 +++++- 9 files changed, 181 insertions(+), 13 deletions(-) diff --git a/scripts/build-web.sh b/scripts/build-web.sh index 360e7aec..5fabb8fb 100755 --- a/scripts/build-web.sh +++ b/scripts/build-web.sh @@ -203,8 +203,11 @@ execute_vite_build() { local mode="$1" log_info "Executing Vite build for $mode mode..." + # Set git hash environment variable + export VITE_GIT_HASH=$(git log -1 --pretty=format:%h) + # Construct Vite build command - local vite_cmd="VITE_GIT_HASH=\$(git log -1 --pretty=format:%h) npx vite build --config vite.config.web.mts" + local vite_cmd="npx vite build --config vite.config.web.mts" # Add mode if not development (development is default) if [ "$mode" != "development" ]; then @@ -256,8 +259,11 @@ execute_docker_build() { start_dev_server() { log_info "Starting Vite development server..." + # Set git hash environment variable + export VITE_GIT_HASH=$(git log -1 --pretty=format:%h) + # Construct Vite dev server command - local vite_cmd="VITE_GIT_HASH=\$(git log -1 --pretty=format:%h) npx vite --config vite.config.web.mts" + local vite_cmd="npx vite --config vite.config.web.mts" # Add mode if specified (though development is default) if [ "$BUILD_MODE" != "development" ]; then @@ -266,9 +272,11 @@ start_dev_server() { log_debug "Vite dev server command: $vite_cmd" log_info "Starting development server on http://localhost:8080" + log_info "Press Ctrl+C to stop the server" # Start the development server (this will block and run the server) - eval "$vite_cmd" + # Note: This command will not return until the server is stopped + exec $vite_cmd } # Function to serve build locally diff --git a/src/registerSQLWorker.js b/src/registerSQLWorker.js index 890e1762..a6c32046 100644 --- a/src/registerSQLWorker.js +++ b/src/registerSQLWorker.js @@ -14,6 +14,81 @@ * @since 2025-07-02 */ +// Polyfill for window object in worker context +// SQL.js expects window to be available, but workers don't have it +if (typeof window === "undefined") { + // Create a minimal window polyfill for SQL.js + globalThis.window = globalThis; + + // Add other browser globals that SQL.js might need + if (typeof globalThis.document === "undefined") { + globalThis.document = { + createElement: () => ({}), + getElementById: () => null, + querySelector: () => null, + addEventListener: () => {}, + removeEventListener: () => {}, + }; + } + + if (typeof globalThis.navigator === "undefined") { + globalThis.navigator = { + userAgent: "Worker", + platform: "Worker", + language: "en-US", + languages: ["en-US"], + cookieEnabled: false, + onLine: true, + }; + } + + if (typeof globalThis.location === "undefined") { + globalThis.location = { + href: "worker://", + origin: "worker://", + protocol: "worker:", + host: "", + hostname: "", + port: "", + pathname: "/", + search: "", + hash: "", + }; + } + + if (typeof globalThis.history === "undefined") { + globalThis.history = { + pushState: () => {}, + replaceState: () => {}, + go: () => {}, + back: () => {}, + forward: () => {}, + }; + } + + if (typeof globalThis.localStorage === "undefined") { + globalThis.localStorage = { + getItem: () => null, + setItem: () => {}, + removeItem: () => {}, + clear: () => {}, + key: () => null, + length: 0, + }; + } + + if (typeof globalThis.sessionStorage === "undefined") { + globalThis.sessionStorage = { + getItem: () => null, + setItem: () => {}, + removeItem: () => {}, + clear: () => {}, + key: () => null, + length: 0, + }; + } +} + import { logger } from "./utils/logger"; /** diff --git a/src/test/EntityGridFunctionPropTest.vue b/src/test/EntityGridFunctionPropTest.vue index 91796f7c..de070af5 100644 --- a/src/test/EntityGridFunctionPropTest.vue +++ b/src/test/EntityGridFunctionPropTest.vue @@ -167,7 +167,7 @@ export default class EntityGridFunctionPropTest extends Vue { _entityType: string, _maxItems: number, ): PlanData[] => { - return entities.sort((a, b) => a.name.localeCompare(b.name)).slice(0, 3); + return entities.sort((a, entityB) => a.name.localeCompare(entityB.name)).slice(0, 3); }; /** diff --git a/src/views/ContactAmountsView.vue b/src/views/ContactAmountsView.vue index 233ddbce..f1e3d10a 100644 --- a/src/views/ContactAmountsView.vue +++ b/src/views/ContactAmountsView.vue @@ -289,8 +289,8 @@ export default class ContactAmountssView extends Vue { } const sortedResult: Array = R.sort( - (a, b) => - new Date(b.issuedAt).getTime() - new Date(a.issuedAt).getTime(), + (a, contactB) => + new Date(contactB.issuedAt).getTime() - new Date(a.issuedAt).getTime(), result, ); this.giveRecords = sortedResult; diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue index 59584c71..5a088ad5 100644 --- a/src/views/ContactsView.vue +++ b/src/views/ContactsView.vue @@ -804,7 +804,7 @@ export default class ContactsView extends Vue { private updateContactsList(newContact: Contact): void { const allContacts = this.contacts.concat([newContact]); this.contacts = R.sort( - (a: Contact, b) => (a.name || "").localeCompare(b.name || ""), + (a: Contact, contactB) => (a.name || "").localeCompare(contactB.name || ""), allContacts, ); } diff --git a/src/views/ImportDerivedAccountView.vue b/src/views/ImportDerivedAccountView.vue index 182c9449..204b3da5 100644 --- a/src/views/ImportDerivedAccountView.vue +++ b/src/views/ImportDerivedAccountView.vue @@ -153,10 +153,10 @@ export default class ImportAccountView extends Vue { const derivationPaths = selectedArray.map( (account) => account.derivationPath, ); - derivationPaths.sort((a, b) => { + derivationPaths.sort((a, pathB) => { const aParts = a?.split("/"); const aLast = aParts?.[aParts.length - 1]; - const bParts = b?.split("/"); + const bParts = pathB?.split("/"); const bLast = bParts?.[bParts.length - 1]; return parseInt(aLast || "0") - parseInt(bLast || "0"); }); diff --git a/vite.config.common.mts b/vite.config.common.mts index b095c293..71a82fa9 100644 --- a/vite.config.common.mts +++ b/vite.config.common.mts @@ -12,17 +12,66 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export async function createBuildConfig(platform: string): Promise { + console.log(`[VITE CONFIG] createBuildConfig called with platform: ${platform}`); + console.log(`[VITE CONFIG] NODE_ENV: ${process.env.NODE_ENV}`); + console.log(`[VITE CONFIG] VITE_PLATFORM: ${process.env.VITE_PLATFORM}`); + const appConfig = await loadAppConfig(); const isCapacitor = platform === "capacitor"; const isElectron = platform === "electron"; const isNative = isCapacitor || isElectron; + console.log(`[VITE CONFIG] Platform flags - isCapacitor: ${isCapacitor}, isElectron: ${isElectron}, isNative: ${isNative}`); + // Set platform - PWA is always enabled for web platforms process.env.VITE_PLATFORM = platform; + console.log(`[VITE CONFIG] Set VITE_PLATFORM to: ${platform}`); - return { + const config: UserConfig = { base: "/", - plugins: [vue()], + plugins: [ + { + name: 'vite-config-logger', + config(config, { command, mode }) { + console.log(`[VITE CONFIG] Plugin config called - command: ${command}, mode: ${mode}`); + console.log(`[VITE CONFIG] Current config keys:`, Object.keys(config || {})); + return config; + }, + configResolved(config) { + console.log(`[VITE CONFIG] Config resolved - mode: ${config.mode}, command: ${config.command}`); + console.log(`[VITE CONFIG] Plugins found:`, config.plugins.map(p => p.name).filter(Boolean)); + console.log(`[VITE CONFIG] Build target:`, config.build?.target); + console.log(`[VITE CONFIG] Minify setting:`, config.build?.minify); + } + }, + // Plugin to explicitly handle HTML elements that Vue might treat as components + { + name: 'vue-html-elements', + transform(code, id) { + if (id.endsWith('.vue')) { + console.log(`[VUE HTML PLUGIN] Processing Vue file: ${id}`); + // This plugin ensures that HTML elements like are treated as HTML elements + // The actual transformation is handled by the Vue compiler configuration above + } + return code; + } + }, + vue({ + template: { + compilerOptions: { + isCustomElement: (tag) => { + console.log(`[VUE COMPILER] isCustomElement called for tag: "${tag}"`); + // Only treat SVG elements as custom elements + // This prevents warnings when using v-html with SVG content from libraries like jdenticon + // Don't treat single-letter tags as custom elements to avoid Vue warnings about , , etc. + const result = tag.startsWith('svg') || tag.startsWith('SVG'); + console.log(`[VUE COMPILER] isCustomElement result for "${tag}": ${result}`); + return result; + } + } + } + }) + ], server: { port: parseInt(process.env.VITE_PORT || "8080"), fs: { strict: false }, @@ -93,6 +142,11 @@ export async function createBuildConfig(platform: string): Promise { ] : [] } }; + + console.log(`[VITE CONFIG] Final config object keys:`, Object.keys(config)); + console.log(`[VITE CONFIG] Vue plugin configuration:`, JSON.stringify(config.plugins?.find(p => typeof p === 'object' && p && 'name' in p && p.name === 'vue') || 'Not found')); + + return config; } export default defineConfig(async () => createBuildConfig('web')); diff --git a/vite.config.optimized.mts b/vite.config.optimized.mts index 5005ac5a..9a288218 100644 --- a/vite.config.optimized.mts +++ b/vite.config.optimized.mts @@ -29,7 +29,23 @@ export async function createOptimizedBuildConfig(mode: string): Promise { + console.log(`[VUE OPTIMIZED] isCustomElement called for tag: "${tag}"`); + // Only treat SVG elements as custom elements + // This prevents warnings when using v-html with SVG content from libraries like jdenticon + // Don't treat single-letter tags as custom elements to avoid Vue warnings about , , etc. + const result = tag.startsWith('svg') || tag.startsWith('SVG'); + console.log(`[VUE OPTIMIZED] isCustomElement result for "${tag}": ${result}`); + return result; + } + } + } + }) + ], server: { port: parseInt(process.env.VITE_PORT || "8080"), fs: { strict: false }, diff --git a/vite.config.web.mts b/vite.config.web.mts index 0744a825..b445734f 100644 --- a/vite.config.web.mts +++ b/vite.config.web.mts @@ -3,7 +3,12 @@ import { createBuildConfig } from "./vite.config.common.mts"; import { loadAppConfig } from "./vite.config.utils.mts"; export default defineConfig(async ({ mode }) => { + console.log(`[VITE WEB CONFIG] Web config called with mode: ${mode}`); + console.log(`[VITE WEB CONFIG] NODE_ENV: ${process.env.NODE_ENV}`); + const baseConfig = await createBuildConfig('web'); + console.log(`[VITE WEB CONFIG] Base config loaded, plugins count: ${baseConfig.plugins?.length || 0}`); + const appConfig = await loadAppConfig(); // Environment-specific configuration based on mode @@ -72,8 +77,9 @@ export default defineConfig(async ({ mode }) => { }; const environmentConfig = getEnvironmentConfig(mode); + console.log(`[VITE WEB CONFIG] Environment config for mode ${mode}:`, Object.keys(environmentConfig)); - return mergeConfig(baseConfig, { + const finalConfig = mergeConfig(baseConfig, { ...environmentConfig, // Ensure source maps are enabled for development and test modes // This affects both dev server and build output @@ -82,4 +88,13 @@ export default defineConfig(async ({ mode }) => { // CORS headers removed to allow images from any domain plugins: [] }); + + console.log(`[VITE WEB CONFIG] Final web config plugins:`, finalConfig.plugins?.map(p => typeof p === 'object' && p && 'name' in p ? p.name : 'unnamed').filter(Boolean)); + console.log(`[VITE WEB CONFIG] Final web config build settings:`, { + minify: finalConfig.build?.minify, + sourcemap: finalConfig.sourcemap, + mode: finalConfig.mode + }); + + return finalConfig; });