From b6f70dd489afd8b8e26d3af2b6b684bec2cdc9f2 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Tue, 6 Jan 2026 18:57:33 -0800 Subject: [PATCH] fix(vite): dynamic and static import mixed usage --- packages/vite/helpers/main-entry.ts | 63 +++++++++++++++++------------ 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/packages/vite/helpers/main-entry.ts b/packages/vite/helpers/main-entry.ts index 7e5833ffa3..de6f986ea7 100644 --- a/packages/vite/helpers/main-entry.ts +++ b/packages/vite/helpers/main-entry.ts @@ -106,6 +106,8 @@ export function mainEntryPlugin(opts: { platform: 'ios' | 'android' | 'visionos' } // ---- Platform-specific always-needed modules ---- + // Track if we need to defer Android activity import (non-HMR only) + let needsAndroidActivityDefer = false; if (opts.platform === 'android') { if (opts.hmrActive) { /** @@ -142,26 +144,10 @@ export function mainEntryPlugin(opts: { platform: 'ios' | 'android' | 'visionos' /** * Non-HMR: Defer activity lifecycle wiring until native Application is ready * to avoid "application is null" errors at production boot. + * We set a flag here and emit the actual code after the static Application import + * to avoid mixing dynamic and static imports of @nativescript/core. */ - imports += ` - (function __nsDeferAndroidActivityImport(){ - const load = () => { try { import('@nativescript/core/ui/frame/activity.android.js?ns-keep'); } catch (e) { console.error('[ns-entry] failed to import android activity module', e); } }; - try { - import('@nativescript/core').then(({ Application: __NS_Application }) => { - try { - const hasApp = !!(__NS_Application && __NS_Application.android && __NS_Application.android.nativeApp); - if (hasApp) { - ${opts.verbose ? "console.info('[ns-entry] android activity import: nativeApp present, loading now');" : ''} - load(); - } else { - ${opts.verbose ? "console.info('[ns-entry] android activity import: deferring until launch/nativeApp');" : ''} - try { __NS_Application.on && __NS_Application.on(__NS_Application.launchEvent, load); } catch {} - try { setTimeout(load, 0); } catch {} - } - } catch { try { setTimeout(load, 0); } catch {} } - }).catch(() => { try { setTimeout(load, 0); } catch {} }); - } catch { try { setTimeout(load, 0); } catch {} } - })();\n`; + needsAndroidActivityDefer = true; } } @@ -189,16 +175,43 @@ export function mainEntryPlugin(opts: { platform: 'ios' | 'android' | 'visionos' // ---- Global CSS injection (always-needed if file exists) ---- const appCssPath = path.resolve(projectRoot, getProjectAppRelativePath('app.css')); - if (fs.existsSync(appCssPath)) { - imports += `// Import and apply global CSS before app bootstrap\n`; - imports += `import appCssContent from './${appRootDir}/app.css?inline';\n`; + const hasAppCss = fs.existsSync(appCssPath); + + // Import Application statically if needed for CSS or Android activity defer + if (hasAppCss || needsAndroidActivityDefer) { + if (hasAppCss) { + imports += `// Import and apply global CSS before app bootstrap\n`; + imports += `import appCssContent from './${appRootDir}/app.css?inline';\n`; + } imports += `import { Application } from '@nativescript/core';\n`; - imports += `if (appCssContent) { try { Application.addCss(appCssContent); } catch (error) { console.error('Error applying CSS:', error); } }\n`; - if (opts.verbose) { - imports += `console.info('[ns-entry] app.css applied');\n`; + if (hasAppCss) { + imports += `if (appCssContent) { try { Application.addCss(appCssContent); } catch (error) { console.error('Error applying CSS:', error); } }\n`; + if (opts.verbose) { + imports += `console.info('[ns-entry] app.css applied');\n`; + } } } + // ---- Deferred Android activity import (non-HMR only) ---- + // Uses the statically imported Application to avoid mixing dynamic and static imports + if (needsAndroidActivityDefer) { + imports += ` + (function __nsDeferAndroidActivityImport(){ + const load = () => { try { import('@nativescript/core/ui/frame/activity.android.js?ns-keep'); } catch (e) { console.error('[ns-entry] failed to import android activity module', e); } }; + try { + const hasApp = !!(Application && Application.android && Application.android.nativeApp); + if (hasApp) { + ${opts.verbose ? "console.info('[ns-entry] android activity import: nativeApp present, loading now');" : ''} + load(); + } else { + ${opts.verbose ? "console.info('[ns-entry] android activity import: deferring until launch/nativeApp');" : ''} + try { Application.on && Application.on(Application.launchEvent, load); } catch {} + try { setTimeout(load, 0); } catch {} + } + } catch { try { setTimeout(load, 0); } catch {} } + })();\n`; + } + // ---- Application main entry ---- if (opts.hmrActive) { // HTTP-only dev boot: try to import the entire app over HTTP; if not reachable, keep retrying.