v1.0.65 fixed the runtime crash (bundling @capacitor/core) but broke the
CAPACITOR_BUILD by also un-externalizing nostr-signer-capacitor-plugin —
which is installed from GitHub with a broken package entry point and
cannot be bundled ("Failed to resolve entry for package").
Correct split:
- BUNDLE @capacitor/core & @capacitor/camera (installed, statically
imported, real JS the WebView needs) — this is the white-screen fix.
- KEEP EXTERNAL nostr-signer-capacitor-plugin — no valid entry point;
only used via a guarded dynamic import() at runtime on native
(try/catch → null on failure), so external is correct and safe.
- KEEP EXTERNAL the four non-installed @capacitor/* plugins.
Verified: built bundle has no bare static @capacitor/core specifier;
signer plugin remains an external dynamic import. Bump to 1.0.66.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
119 lines
4.3 KiB
TypeScript
119 lines
4.3 KiB
TypeScript
import path from "node:path";
|
|
|
|
import react from "@vitejs/plugin-react-swc";
|
|
import { defineConfig } from "vitest/config";
|
|
|
|
// https://vitejs.dev/config/
|
|
export default defineConfig(() => ({
|
|
// In a native Capacitor WebView the bundle is served from the local
|
|
// filesystem, so assets must be referenced with RELATIVE paths ('./…').
|
|
// Absolute '/…' paths are the classic cause of a white screen on device.
|
|
// The regular web deploy keeps '/' (served from a domain root).
|
|
base: process.env.CAPACITOR_BUILD ? './' : '/',
|
|
server: {
|
|
host: "::",
|
|
port: 8080,
|
|
},
|
|
plugins: [
|
|
react(),
|
|
],
|
|
test: {
|
|
globals: true,
|
|
environment: 'jsdom',
|
|
setupFiles: './src/test/setup.ts',
|
|
onConsoleLog(log) {
|
|
return !log.includes("React Router Future Flag Warning");
|
|
},
|
|
env: {
|
|
DEBUG_PRINT_LIMIT: '0',
|
|
},
|
|
},
|
|
resolve: {
|
|
alias: {
|
|
"@": path.resolve(__dirname, "./src"),
|
|
},
|
|
},
|
|
optimizeDeps: {
|
|
exclude: ['@lightninglabs/lnc-web'],
|
|
},
|
|
|
|
build: {
|
|
// Strip console.log/warn/debug in production (keeps console.error for real errors)
|
|
minify: 'esbuild',
|
|
commonjsOptions: {
|
|
transformMixedEsModules: true,
|
|
},
|
|
rollupOptions: {
|
|
// IMPORTANT: @capacitor/core and @capacitor/camera MUST be bundled (they are
|
|
// installed, statically imported, and their JS API layer is real code the
|
|
// WebView needs). Leaving them external emitted a bare `import "@capacitor/core"`
|
|
// specifier that a native WebView cannot resolve → white-screen boot crash.
|
|
// They are therefore intentionally ABSENT from this list.
|
|
//
|
|
// Kept external:
|
|
// - nostr-signer-capacitor-plugin: installed from GitHub with a broken package
|
|
// entry point, so it CANNOT be bundled. It's only ever used via a guarded
|
|
// dynamic import() at runtime on native (see lib/capacitorAmberSigner.ts,
|
|
// wrapped in try/catch → returns null on failure), so external is correct
|
|
// and safe — a resolution failure degrades gracefully instead of crashing.
|
|
// - @capacitor/app|haptics|keyboard|status-bar: NOT installed and never
|
|
// statically imported (accessed via window.Capacitor.Plugins), so keeping
|
|
// them external prevents a stray import from breaking the build.
|
|
external: [
|
|
'nostr-signer-capacitor-plugin',
|
|
'@capacitor/app',
|
|
'@capacitor/haptics',
|
|
'@capacitor/keyboard',
|
|
'@capacitor/status-bar',
|
|
],
|
|
output: process.env.CAPACITOR_BUILD ? {
|
|
// Single bundle for Capacitor APK — avoids 100+ chunk file requests
|
|
// that fail silently in Android WebView local file serving
|
|
manualChunks: undefined,
|
|
inlineDynamicImports: true,
|
|
} : {
|
|
// Split large vendor libraries into separate cacheable chunks.
|
|
// Users only re-download a chunk when that specific library updates.
|
|
manualChunks(id) {
|
|
// Map — Leaflet is large (~150KB), isolate it so non-map pages don't pay for it
|
|
if (id.includes('leaflet') || id.includes('ngeohash')) {
|
|
return 'vendor-map';
|
|
}
|
|
// Nostr core — changes infrequently, worth caching separately
|
|
if (id.includes('nostr-tools') || id.includes('@nostrify') || id.includes('@noble')) {
|
|
return 'vendor-nostr';
|
|
}
|
|
// Bitcoin / Lightning — large, rarely changes
|
|
if (
|
|
id.includes('@cashu') ||
|
|
id.includes('bitcoinjs-lib') ||
|
|
id.includes('@scure') ||
|
|
id.includes('@bitcoinerlab') ||
|
|
id.includes('ecpair') ||
|
|
id.includes('@getalby') ||
|
|
id.includes('npubcash')
|
|
) {
|
|
return 'vendor-bitcoin';
|
|
}
|
|
// React ecosystem — very stable, long cache life
|
|
if (id.includes('react-dom') || id.includes('react-router')) {
|
|
return 'vendor-react';
|
|
}
|
|
// Radix UI components — large but stable
|
|
if (id.includes('@radix-ui')) {
|
|
return 'vendor-radix';
|
|
}
|
|
// TanStack Query
|
|
if (id.includes('@tanstack')) {
|
|
return 'vendor-query';
|
|
}
|
|
},
|
|
},
|
|
},
|
|
},
|
|
// Strip console.log/warn/debug calls from production build
|
|
esbuild: {
|
|
drop: ['debugger'],
|
|
pure: ['console.log', 'console.warn', 'console.debug'],
|
|
},
|
|
}));
|