Fix native build: access Camera via runtime plugin, not @capacitor/camera import
Local CAPACITOR_BUILD failed: Rollup couldn't resolve import
"@capacitor/camera" from CameraCapture.tsx — the package is listed in
package.json but isn't present in node_modules on the build machine.
Root pattern (same class as the @capacitor/core crash): a package that
must NOT be resolved at build time was being imported by specifier.
Fix:
- CameraCapture.tsx no longer imports '@capacitor/camera' at all. The
Camera plugin is accessed via the runtime-injected
window.Capacitor.Plugins.Camera (Capacitor injects it natively), using
string enum values ('dataUrl' / 'CAMERA'). No bare specifier remains in
the bundle, and it degrades gracefully if the plugin is absent.
- vite.config: @capacitor/camera moved back to `external` (belt-and-braces;
it's no longer imported anyway). @capacitor/core stays BUNDLED (static
import in platform.ts — the white-screen fix). nostr-signer-capacitor-plugin
and the 4 uninstalled @capacitor/* plugins remain external.
Verified: no @capacitor/camera specifier and no unresolved @capacitor/core
import in the built bundle; no static imports of any externalized package
remain in src/. Bump to 1.0.67.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
parent
ac362a9a10
commit
3a96184001
3 changed files with 45 additions and 18 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "skate-spots",
|
"name": "skate-spots",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.66",
|
"version": "1.0.67",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"homepage": "https://skate-spots.com",
|
"homepage": "https://skate-spots.com",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,34 @@ async function isNative(): Promise<boolean> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The Camera plugin is provided by Capacitor at runtime on native. We access it
|
||||||
|
// through the runtime-injected `window.Capacitor.Plugins.Camera` rather than a
|
||||||
|
// static/dynamic `import('@capacitor/camera')`, so the bundle contains no bare
|
||||||
|
// `@capacitor/camera` specifier (which a native WebView can't resolve, and which
|
||||||
|
// isn't installed on every build machine). CameraResultType/CameraSource are
|
||||||
|
// plain string enums in the plugin, so we pass their string values directly.
|
||||||
|
interface CapacitorCameraPlugin {
|
||||||
|
getPhoto(options: {
|
||||||
|
resultType: string;
|
||||||
|
source: string;
|
||||||
|
quality: number;
|
||||||
|
correctOrientation: boolean;
|
||||||
|
}): Promise<{ dataUrl?: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNativeCamera(): CapacitorCameraPlugin | null {
|
||||||
|
const cap = (window as unknown as {
|
||||||
|
Capacitor?: { Plugins?: { Camera?: CapacitorCameraPlugin } };
|
||||||
|
}).Capacitor;
|
||||||
|
return cap?.Plugins?.Camera ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
async function captureNative(): Promise<File | null> {
|
async function captureNative(): Promise<File | null> {
|
||||||
const { Camera, CameraResultType, CameraSource } = await import('@capacitor/camera');
|
const Camera = getNativeCamera();
|
||||||
|
if (!Camera) throw new Error('Camera plugin unavailable');
|
||||||
const photo = await Camera.getPhoto({
|
const photo = await Camera.getPhoto({
|
||||||
resultType: CameraResultType.DataUrl,
|
resultType: 'dataUrl', // CameraResultType.DataUrl
|
||||||
source: CameraSource.Camera,
|
source: 'CAMERA', // CameraSource.Camera
|
||||||
quality: 90,
|
quality: 90,
|
||||||
correctOrientation: true,
|
correctOrientation: true,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -44,22 +44,26 @@ export default defineConfig(() => ({
|
||||||
transformMixedEsModules: true,
|
transformMixedEsModules: true,
|
||||||
},
|
},
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
// IMPORTANT: @capacitor/core and @capacitor/camera MUST be bundled (they are
|
// Bundling policy — the distinction that matters is STATIC vs DYNAMIC import,
|
||||||
// installed, statically imported, and their JS API layer is real code the
|
// and whether the package resolves on the build machine:
|
||||||
// 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:
|
// BUNDLED (absent from this list):
|
||||||
// - nostr-signer-capacitor-plugin: installed from GitHub with a broken package
|
// - @capacitor/core — imported STATICALLY (lib/platform.ts). It MUST be
|
||||||
// entry point, so it CANNOT be bundled. It's only ever used via a guarded
|
// bundled: leaving it external emitted a bare `import "@capacitor/core"`
|
||||||
// dynamic import() at runtime on native (see lib/capacitorAmberSigner.ts,
|
// specifier the native WebView can't resolve → white-screen boot crash.
|
||||||
// wrapped in try/catch → returns null on failure), so external is correct
|
// Capacitor guarantees core is installed, so bundling always resolves.
|
||||||
// and safe — a resolution failure degrades gracefully instead of crashing.
|
//
|
||||||
// - @capacitor/app|haptics|keyboard|status-bar: NOT installed and never
|
// EXTERNAL (listed below):
|
||||||
// statically imported (accessed via window.Capacitor.Plugins), so keeping
|
// - @capacitor/camera — used only via a GUARDED dynamic import() on native
|
||||||
// them external prevents a stray import from breaking the build.
|
// (components/CameraCapture.tsx). It may not be installed on every build
|
||||||
|
// machine, and it's optional/native-only, so it must stay external. The
|
||||||
|
// dynamic import() remains a runtime call that degrades gracefully.
|
||||||
|
// - nostr-signer-capacitor-plugin — installed from GitHub with a broken
|
||||||
|
// package entry point; cannot be bundled. Guarded dynamic import() only.
|
||||||
|
// - @capacitor/app|haptics|keyboard|status-bar — NOT installed and never
|
||||||
|
// statically imported (accessed via window.Capacitor.Plugins at runtime).
|
||||||
external: [
|
external: [
|
||||||
|
'@capacitor/camera',
|
||||||
'nostr-signer-capacitor-plugin',
|
'nostr-signer-capacitor-plugin',
|
||||||
'@capacitor/app',
|
'@capacitor/app',
|
||||||
'@capacitor/haptics',
|
'@capacitor/haptics',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue