Browse Source

grr: experimental diagnosis and fix for build:web:serve

web-serve-fix
Matthew Raymer 1 week ago
parent
commit
2e290ad488
  1. 14
      scripts/build-web.sh
  2. 75
      src/registerSQLWorker.js
  3. 2
      src/test/EntityGridFunctionPropTest.vue
  4. 4
      src/views/ContactAmountsView.vue
  5. 2
      src/views/ContactsView.vue
  6. 4
      src/views/ImportDerivedAccountView.vue
  7. 58
      vite.config.common.mts
  8. 18
      vite.config.optimized.mts
  9. 17
      vite.config.web.mts

14
scripts/build-web.sh

@ -203,8 +203,11 @@ execute_vite_build() {
local mode="$1" local mode="$1"
log_info "Executing Vite build for $mode mode..." 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 # 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) # Add mode if not development (development is default)
if [ "$mode" != "development" ]; then if [ "$mode" != "development" ]; then
@ -256,8 +259,11 @@ execute_docker_build() {
start_dev_server() { start_dev_server() {
log_info "Starting Vite development 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 # 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) # Add mode if specified (though development is default)
if [ "$BUILD_MODE" != "development" ]; then if [ "$BUILD_MODE" != "development" ]; then
@ -266,9 +272,11 @@ start_dev_server() {
log_debug "Vite dev server command: $vite_cmd" log_debug "Vite dev server command: $vite_cmd"
log_info "Starting development server on http://localhost:8080" 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) # 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 # Function to serve build locally

75
src/registerSQLWorker.js

@ -14,6 +14,81 @@
* @since 2025-07-02 * @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"; import { logger } from "./utils/logger";
/** /**

2
src/test/EntityGridFunctionPropTest.vue

@ -167,7 +167,7 @@ export default class EntityGridFunctionPropTest extends Vue {
_entityType: string, _entityType: string,
_maxItems: number, _maxItems: number,
): PlanData[] => { ): 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);
}; };
/** /**

4
src/views/ContactAmountsView.vue

@ -289,8 +289,8 @@ export default class ContactAmountssView extends Vue {
} }
const sortedResult: Array<GiveSummaryRecord> = R.sort( const sortedResult: Array<GiveSummaryRecord> = R.sort(
(a, b) => (a, contactB) =>
new Date(b.issuedAt).getTime() - new Date(a.issuedAt).getTime(), new Date(contactB.issuedAt).getTime() - new Date(a.issuedAt).getTime(),
result, result,
); );
this.giveRecords = sortedResult; this.giveRecords = sortedResult;

2
src/views/ContactsView.vue

@ -804,7 +804,7 @@ export default class ContactsView extends Vue {
private updateContactsList(newContact: Contact): void { private updateContactsList(newContact: Contact): void {
const allContacts = this.contacts.concat([newContact]); const allContacts = this.contacts.concat([newContact]);
this.contacts = R.sort( this.contacts = R.sort(
(a: Contact, b) => (a.name || "").localeCompare(b.name || ""), (a: Contact, contactB) => (a.name || "").localeCompare(contactB.name || ""),
allContacts, allContacts,
); );
} }

4
src/views/ImportDerivedAccountView.vue

@ -153,10 +153,10 @@ export default class ImportAccountView extends Vue {
const derivationPaths = selectedArray.map( const derivationPaths = selectedArray.map(
(account) => account.derivationPath, (account) => account.derivationPath,
); );
derivationPaths.sort((a, b) => { derivationPaths.sort((a, pathB) => {
const aParts = a?.split("/"); const aParts = a?.split("/");
const aLast = aParts?.[aParts.length - 1]; const aLast = aParts?.[aParts.length - 1];
const bParts = b?.split("/"); const bParts = pathB?.split("/");
const bLast = bParts?.[bParts.length - 1]; const bLast = bParts?.[bParts.length - 1];
return parseInt(aLast || "0") - parseInt(bLast || "0"); return parseInt(aLast || "0") - parseInt(bLast || "0");
}); });

58
vite.config.common.mts

@ -12,17 +12,66 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
export async function createBuildConfig(platform: string): Promise<UserConfig> { export async function createBuildConfig(platform: string): Promise<UserConfig> {
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 appConfig = await loadAppConfig();
const isCapacitor = platform === "capacitor"; const isCapacitor = platform === "capacitor";
const isElectron = platform === "electron"; const isElectron = platform === "electron";
const isNative = isCapacitor || isElectron; 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 // Set platform - PWA is always enabled for web platforms
process.env.VITE_PLATFORM = platform; process.env.VITE_PLATFORM = platform;
console.log(`[VITE CONFIG] Set VITE_PLATFORM to: ${platform}`);
return { const config: UserConfig = {
base: "/", 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 <b> 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 <b>, <i>, etc.
const result = tag.startsWith('svg') || tag.startsWith('SVG');
console.log(`[VUE COMPILER] isCustomElement result for "${tag}": ${result}`);
return result;
}
}
}
})
],
server: { server: {
port: parseInt(process.env.VITE_PORT || "8080"), port: parseInt(process.env.VITE_PORT || "8080"),
fs: { strict: false }, fs: { strict: false },
@ -93,6 +142,11 @@ export async function createBuildConfig(platform: string): Promise<UserConfig> {
] : [] ] : []
} }
}; };
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')); export default defineConfig(async () => createBuildConfig('web'));

18
vite.config.optimized.mts

@ -29,7 +29,23 @@ export async function createOptimizedBuildConfig(mode: string): Promise<UserConf
return { return {
base: "/", base: "/",
plugins: [vue()], plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => {
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 <b>, <i>, etc.
const result = tag.startsWith('svg') || tag.startsWith('SVG');
console.log(`[VUE OPTIMIZED] isCustomElement result for "${tag}": ${result}`);
return result;
}
}
}
})
],
server: { server: {
port: parseInt(process.env.VITE_PORT || "8080"), port: parseInt(process.env.VITE_PORT || "8080"),
fs: { strict: false }, fs: { strict: false },

17
vite.config.web.mts

@ -3,7 +3,12 @@ import { createBuildConfig } from "./vite.config.common.mts";
import { loadAppConfig } from "./vite.config.utils.mts"; import { loadAppConfig } from "./vite.config.utils.mts";
export default defineConfig(async ({ mode }) => { 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'); const baseConfig = await createBuildConfig('web');
console.log(`[VITE WEB CONFIG] Base config loaded, plugins count: ${baseConfig.plugins?.length || 0}`);
const appConfig = await loadAppConfig(); const appConfig = await loadAppConfig();
// Environment-specific configuration based on mode // Environment-specific configuration based on mode
@ -72,8 +77,9 @@ export default defineConfig(async ({ mode }) => {
}; };
const environmentConfig = getEnvironmentConfig(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, ...environmentConfig,
// Ensure source maps are enabled for development and test modes // Ensure source maps are enabled for development and test modes
// This affects both dev server and build output // 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 // CORS headers removed to allow images from any domain
plugins: [] 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;
}); });

Loading…
Cancel
Save