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"
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

75
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";
/**

2
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);
};
/**

4
src/views/ContactAmountsView.vue

@ -289,8 +289,8 @@ export default class ContactAmountssView extends Vue {
}
const sortedResult: Array<GiveSummaryRecord> = 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;

2
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,
);
}

4
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");
});

58
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<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 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 <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: {
port: parseInt(process.env.VITE_PORT || "8080"),
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'));

18
vite.config.optimized.mts

@ -29,7 +29,23 @@ export async function createOptimizedBuildConfig(mode: string): Promise<UserConf
return {
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: {
port: parseInt(process.env.VITE_PORT || "8080"),
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";
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;
});

Loading…
Cancel
Save