@nativescript/vite 0.0.1-alpha.1 → 0.0.1-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/configuration/base.js +134 -36
  2. package/dist/helpers/external-configs.js +1 -1
  3. package/dist/helpers/global-defines.d.ts +1 -0
  4. package/dist/helpers/global-defines.js +2 -0
  5. package/dist/helpers/main-entry-hmr-includes.d.ts +1 -0
  6. package/dist/helpers/main-entry-hmr-includes.js +18 -0
  7. package/dist/helpers/main-entry.d.ts +2 -2
  8. package/dist/helpers/main-entry.js +58 -94
  9. package/dist/helpers/module-runner-patch.d.ts +3 -0
  10. package/dist/helpers/module-runner-patch.js +65 -0
  11. package/dist/helpers/ns-cli-plugins.d.ts +1 -14
  12. package/dist/helpers/ns-cli-plugins.js +54 -107
  13. package/dist/helpers/package-platform-aliases.d.ts +1 -1
  14. package/dist/helpers/package-platform-aliases.js +4 -4
  15. package/dist/helpers/ts-config-paths.d.ts +1 -1
  16. package/dist/helpers/ts-config-paths.js +3 -3
  17. package/dist/hmr/client-vue.d.ts +6 -0
  18. package/dist/hmr/client-vue.js +563 -0
  19. package/dist/hmr/component-tracker.d.ts +23 -0
  20. package/dist/hmr/component-tracker.js +193 -0
  21. package/dist/hmr/css-handler.d.ts +4 -0
  22. package/dist/hmr/css-handler.js +77 -0
  23. package/dist/hmr/message-handler.d.ts +1 -0
  24. package/dist/hmr/message-handler.js +590 -0
  25. package/dist/hmr/nsv-hooks.d.ts +2 -0
  26. package/dist/hmr/nsv-hooks.js +481 -0
  27. package/dist/hmr/plugin-vue.d.ts +2 -0
  28. package/dist/hmr/plugin-vue.js +38 -0
  29. package/dist/hmr/plugins/index.d.ts +1 -0
  30. package/dist/hmr/plugins/index.js +16 -0
  31. package/dist/hmr/plugins/plugin-vue.d.ts +2 -0
  32. package/dist/hmr/plugins/plugin-vue.js +41 -0
  33. package/dist/hmr/plugins/websocket-vue.d.ts +2 -0
  34. package/dist/hmr/plugins/websocket-vue.js +882 -0
  35. package/dist/hmr/runtime-vue.d.ts +13 -0
  36. package/dist/hmr/runtime-vue.js +2306 -0
  37. package/dist/hmr/types.d.ts +24 -0
  38. package/dist/hmr/types.js +2 -0
  39. package/dist/hmr/websocket-vue.d.ts +2 -0
  40. package/dist/hmr/websocket-vue.js +875 -0
  41. package/dist/shims/node-module.d.ts +5 -0
  42. package/dist/shims/node-module.js +12 -0
  43. package/package.json +2 -1
  44. package/dist/configuration/old-without-merge-base.d.ts +0 -13
  45. package/dist/configuration/old-without-merge-base.js +0 -249
  46. package/dist/helpers/side-effects.d.ts +0 -14
  47. package/dist/helpers/side-effects.js +0 -69
  48. package/dist/hmr/hmr-angular.d.ts +0 -1
  49. package/dist/hmr/hmr-angular.js +0 -34
  50. package/dist/hmr/hmr-bridge.d.ts +0 -18
  51. package/dist/hmr/hmr-bridge.js +0 -154
  52. package/dist/hmr/hmr-client.d.ts +0 -5
  53. package/dist/hmr/hmr-client.js +0 -93
  54. package/dist/hmr/hmr-server.d.ts +0 -20
  55. package/dist/hmr/hmr-server.js +0 -179
@@ -1,8 +1,11 @@
1
- import { mergeConfig } from "vite";
1
+ import { mergeConfig, createLogger } from "vite";
2
2
  import path from "path";
3
- import { existsSync } from "fs";
3
+ import { existsSync, readFileSync } from "fs";
4
+ import { createRequire } from "node:module";
5
+ import { pathToFileURL } from "node:url";
4
6
  import minimist from "minimist";
5
7
  import commonjs from "@rollup/plugin-commonjs";
8
+ import replace from "@rollup/plugin-replace";
6
9
  import { viteStaticCopy } from "vite-plugin-static-copy";
7
10
  import NativeScriptPlugin from "../helpers/resolver.js";
8
11
  import nsConfigAsJsonPlugin from "../helpers/config-as-json.js";
@@ -14,13 +17,18 @@ import { getWorkerPlugins, workerUrlPlugin } from "../helpers/workers.js";
14
17
  import { getTsConfigData } from "../helpers/ts-config-paths.js";
15
18
  import { commonjsPlugins } from "../helpers/commonjs-plugins.js";
16
19
  import { nativescriptPackageResolver } from "../helpers/nativescript-package-resolver.js";
17
- import { hmrPlugin, cliPlugin } from "../helpers/ns-cli-plugins.js";
20
+ import { cliPlugin } from "../helpers/ns-cli-plugins.js";
18
21
  import { dynamicImportPlugin } from "../helpers/dynamic-import-plugin.js";
19
22
  import { mainEntryPlugin } from "../helpers/main-entry.js";
20
23
  import { determineProjectFlavor } from "../helpers/flavor.js";
21
24
  import { preserveImportsPlugin } from "../helpers/preserve-imports.js";
22
25
  import { externalConfigMerges, applyExternalConfigs, } from "../helpers/external-configs.js";
23
- const debugViteLogs = !!process.env.VITE_DEBUG_PATHS;
26
+ import { getHMRPlugins } from "../hmr/plugins/index.js";
27
+ const require = createRequire(import.meta.url);
28
+ const distOutputFolder = process.env.NS_VITE_DIST_DIR || ".ns-vite-build";
29
+ const verboseLogs = !!process.env.VITE_DEBUG_LOGS;
30
+ // HMR dev server options with socket
31
+ const useHttps = process.env.NS_HTTPS === "1" || process.env.NS_HTTPS === "true";
24
32
  const projectRoot = getProjectRootPath();
25
33
  /**
26
34
  * Plugins can define nativescript.vite.mjs
@@ -28,8 +36,7 @@ const projectRoot = getProjectRootPath();
28
36
  */
29
37
  applyExternalConfigs();
30
38
  export const baseConfig = ({ mode }) => {
31
- const platform = mode;
32
- const targetMode = process.env.production ? "production" : "development";
39
+ const targetMode = mode === "development" ? "development" : "production";
33
40
  const cliArgs = minimist(process.argv.slice(2), { "--": true });
34
41
  const cliFlags = (cliArgs["--"] || []).reduce((obj, flag) => {
35
42
  // remove env prefix
@@ -38,18 +45,46 @@ export const baseConfig = ({ mode }) => {
38
45
  return obj;
39
46
  }, {});
40
47
  // console.log("cliFlags:", cliFlags);
41
- const debug = !!cliFlags.viteDebug || !!process.env.DEBUG || targetMode === "development";
48
+ const isDevMode = targetMode === "development";
49
+ const debug = !!process.env.DEBUG || isDevMode;
50
+ const hmrActive = isDevMode && !!cliFlags.hmr;
51
+ const platform = cliFlags.platform || "ios";
42
52
  if (debug) {
43
53
  console.log("--------------");
44
- console.log("Vite config mode:", mode);
54
+ // console.log("Vite config mode:", mode);
45
55
  console.log("Target mode:", targetMode);
46
56
  console.log("Platform:", platform);
57
+ console.log("HMR active:", hmrActive);
47
58
  console.log("--------------");
48
59
  }
49
60
  const flavor = determineProjectFlavor();
50
61
  console.log(`Building for ${flavor}.`);
62
+ // Suppress extremely noisy sourcemap warnings for third-party packages
63
+ // These occur because published packages often omit original TS sources referenced by their .map files.
64
+ // They have no runtime effect but clutter the console in dev.
65
+ const baseLogger = createLogger(undefined, { allowClearScreen: true });
66
+ const filteredLogger = {
67
+ ...baseLogger,
68
+ warn(message, options) {
69
+ const msg = message;
70
+ if (msg.startsWith("Sourcemap for ") &&
71
+ msg.includes("missing source files")) {
72
+ // Swallow this specific noisy warning
73
+ return;
74
+ }
75
+ return baseLogger.warn(message, options);
76
+ },
77
+ warnOnce(message) {
78
+ const msg = message;
79
+ if (msg.startsWith("Sourcemap for ") &&
80
+ msg.includes("missing source files")) {
81
+ return;
82
+ }
83
+ return baseLogger.warnOnce(message);
84
+ },
85
+ };
51
86
  // Create TypeScript aliases with platform support
52
- const tsConfigData = getTsConfigData(debugViteLogs, platform);
87
+ const tsConfigData = getTsConfigData(verboseLogs, platform);
53
88
  // Common resolve configuration for both main and worker builds
54
89
  // Build platform-aware extension preference order and exclude the opposite platform
55
90
  const platformExtensions = (() => {
@@ -79,15 +114,25 @@ export const baseConfig = ({ mode }) => {
79
114
  dedupe: ["@nativescript/core", "nativescript-vue", "vue"],
80
115
  // Alias "@" and "~" to your src directory for cleaner imports
81
116
  alias: [
117
+ // Provide a shim for node:module to avoid runtime crashes in NS
118
+ {
119
+ find: /^node:module$/,
120
+ replacement: path.resolve(path.dirname(new URL(import.meta.url).pathname), "../shims/node-module.js"),
121
+ },
122
+ // Ensure set-value resolves to an absolute shim to avoid alias warnings and duplication
123
+ [
124
+ {
125
+ find: /^set-value$/,
126
+ replacement: require.resolve("@nativescript/vite/dist/shims/set-value.js"),
127
+ },
128
+ ],
82
129
  ...aliasCssTree,
83
130
  // 1) Catch exactly `~/package.json` → virtual module (MUST be first!)
84
131
  { find: /^~\/package\.json$/, replacement: "~/package.json" },
85
132
  // TypeScript path aliases from tsconfig.json
86
133
  ...tsConfigData.aliases,
87
134
  // Generic platform resolution for any npm package
88
- packagePlatformAliases(tsConfigData, platform,
89
- // skipCommonjsPackages,
90
- debugViteLogs),
135
+ packagePlatformAliases(tsConfigData, platform, verboseLogs),
91
136
  // 2) Catch everything else under "~/" → your src/
92
137
  { find: /^~\/(.*)$/, replacement: path.resolve(projectRoot, "src/$1") },
93
138
  // optional: "@" → src/
@@ -117,21 +162,20 @@ export const baseConfig = ({ mode }) => {
117
162
  staticCopyTargets.push({ src: `${fontsAppDir}/**/*`, dest: "fonts" });
118
163
  }
119
164
  let baseViteConfig = {
165
+ // Suppress logs during HMR development if desired:
166
+ // ...(hmrActive ? { logLevel: "warn" as const } : {}),
167
+ // Filter out noisy sourcemap warnings from dependencies while keeping other warnings intact
168
+ customLogger: filteredLogger,
120
169
  resolve: resolveConfig,
121
- define: defineConfig,
170
+ // Propagate a single verbose flag into the runtime so device-side code can gate logs consistently
171
+ define: {
172
+ ...defineConfig,
173
+ __NS_ENV_VERBOSE__: verboseLogs,
174
+ },
122
175
  // Vite's built-in solution for CommonJS/ESM compatibility issues
123
176
  optimizeDeps: {
124
177
  // Force pre-bundling of problematic CommonJS packages
125
- include: [
126
- // "source-map-js",
127
- "@valor/nativescript-websockets",
128
- // React and related packages for proper module resolution
129
- "react",
130
- "react-reconciler",
131
- "react-nativescript",
132
- // ...(optimizeDeps || []),
133
- // Add any other problematic packages here
134
- ],
178
+ include: [],
135
179
  // Handle Node.js built-ins and other edge cases
136
180
  esbuildOptions: {
137
181
  // Pass the same conditions to ESBuild for css-tree compatibility
@@ -139,6 +183,7 @@ export const baseConfig = ({ mode }) => {
139
183
  // Define globals for Node.js built-ins if needed
140
184
  define: {
141
185
  global: "globalThis",
186
+ "process.env.NODE_ENV": JSON.stringify(debug ? "development" : "production"),
142
187
  },
143
188
  },
144
189
  // Avoid pre-bundling NativeScript core to prevent esbuild from stripping side-effectful modules
@@ -146,11 +191,31 @@ export const baseConfig = ({ mode }) => {
146
191
  "@nativescript/core",
147
192
  "@nativescript/core/ui/frame",
148
193
  "@nativescript/core/ui/frame/activity",
194
+ // Do not prebundle NS-only websocket polyfill or the set-value shim
195
+ "@valor/nativescript-websockets",
196
+ "set-value",
197
+ // Keep React-native related out unless explicitly needed per flavor
198
+ "react",
199
+ "react-reconciler",
200
+ "react-nativescript",
149
201
  ],
150
202
  },
203
+ esbuild: {
204
+ define: {
205
+ "process.env.NODE_ENV": JSON.stringify(debug ? "development" : "production"),
206
+ },
207
+ },
151
208
  plugins: [
209
+ // Ensure Rollup phase replaces in node_modules too
210
+ // Important for various vendor handling
211
+ replace({
212
+ "process.env.NODE_ENV": JSON.stringify(debug ? "development" : "production"),
213
+ preventAssignment: true,
214
+ }),
152
215
  // Ensure explicit keep markers are honored
153
216
  preserveImportsPlugin(),
217
+ // Vue HMR plugins for development mode
218
+ ...(hmrActive ? getHMRPlugins(platform, flavor, verboseLogs) : []),
154
219
  // TODO: make flavor plugins dynamic
155
220
  // ...flavorPlugins,
156
221
  ...commonjsPlugins,
@@ -182,22 +247,35 @@ export const baseConfig = ({ mode }) => {
182
247
  }),
183
248
  ]
184
249
  : []),
185
- // NativeScript HMR integration - track changes for incremental builds
186
- hmrPlugin(targetMode),
187
- // NativeScript CLI integration - enhanced IPC communication for HMR
188
- cliPlugin(targetMode, cliFlags),
250
+ // NativeScript CLI integration
251
+ cliPlugin(distOutputFolder, isDevMode, verboseLogs, hmrActive),
189
252
  ],
190
253
  css: {
191
254
  postcss: "./postcss.config.js",
192
255
  },
193
256
  // Development server configuration for HMR
194
- server: targetMode === "development"
257
+ server: isDevMode
195
258
  ? {
259
+ // Expose dev server to local network so simulator or device can connect
260
+ host: process.env.NS_HMR_HOST ||
261
+ (platform === "android" ? "10.0.0.2" : "localhost"),
262
+ // Use a stable port so the device URL remains correct
263
+ port: 5173,
264
+ strictPort: true,
265
+ https: useHttps
266
+ ? {
267
+ // Optional: allow self-signed certs via env paths
268
+ key: process.env.NS_HTTPS_KEY &&
269
+ readFileSync(process.env.NS_HTTPS_KEY),
270
+ cert: process.env.NS_HTTPS_CERT &&
271
+ readFileSync(process.env.NS_HTTPS_CERT),
272
+ }
273
+ : undefined,
274
+ // Keep HMR on the primary server port (Vite browser client stays on /vite-hmr)
196
275
  hmr: {
197
- // Enable Vite's built-in HMR
198
- port: 24678, // Different port to avoid conflicts with our custom WebSocket
276
+ protocol: useHttps ? "wss" : "ws",
277
+ path: "/vite-hmr",
199
278
  },
200
- // CORS for development
201
279
  cors: true,
202
280
  }
203
281
  : {},
@@ -215,15 +293,23 @@ export const baseConfig = ({ mode }) => {
215
293
  },
216
294
  },
217
295
  build: {
296
+ // Ensure Vite and plugins (like vite-plugin-static-copy) use the same output directory
297
+ outDir: path.resolve(projectRoot, distOutputFolder),
218
298
  target: "esnext",
219
299
  minify: !debug,
220
300
  // Generate source maps for debugging
221
- // Note: just disabling for now until can hook up to angular vite/analog plugin
222
- sourcemap: false, //debug,
301
+ // External sourcemaps so DevTools loads small .mjs files and fetches maps on demand
302
+ sourcemap: debug,
223
303
  // Disable module preloading to avoid browser APIs
224
304
  modulePreload: false,
305
+ // Under HMR, avoid rebuilds on src/** changes — device consumes updates via /ns-hmr
306
+ ...(hmrActive && {
307
+ watch: {
308
+ exclude: ["src/**"],
309
+ },
310
+ }),
225
311
  // Optimize for development speed
226
- ...(targetMode === "development" && {
312
+ ...(isDevMode && {
227
313
  // Faster builds in development
228
314
  reportCompressedSize: false,
229
315
  chunkSizeWarningLimit: 2000,
@@ -239,9 +325,12 @@ export const baseConfig = ({ mode }) => {
239
325
  },
240
326
  input: "virtual:entry-with-polyfills",
241
327
  output: {
242
- dir: path.resolve(projectRoot, "dist"),
243
328
  format: "es", // Emit ES modules (.mjs)
244
- entryFileNames: "bundle.mjs", // <- no hash here
329
+ entryFileNames: "bundle.mjs",
330
+ // Point source map URLs to absolute file:// paths on the host so
331
+ // Chrome DevTools can fetch them even though the running code comes
332
+ // from file:///app on the simulator/device.
333
+ sourcemapBaseUrl: pathToFileURL(path.resolve(projectRoot, distOutputFolder)).toString() + "/",
245
334
  chunkFileNames: (chunk) => {
246
335
  if (chunk.name === "vendor")
247
336
  return "vendor.mjs";
@@ -267,6 +356,15 @@ export const baseConfig = ({ mode }) => {
267
356
  }
268
357
  },
269
358
  },
359
+ // When HMR is active, prevent Vite's build watcher from reacting to src/** changes.
360
+ // The device will get updates via socket /ns-hmr instead.
361
+ ...(hmrActive
362
+ ? {
363
+ watch: {
364
+ exclude: ["src/**"],
365
+ },
366
+ }
367
+ : {}),
270
368
  },
271
369
  },
272
370
  };
@@ -16,7 +16,7 @@ export function applyExternalConfigs() {
16
16
  }
17
17
  const configPath = path.join(packagePath, 'nativescript.vite.mjs');
18
18
  if (fs.existsSync(configPath)) {
19
- console.log(`Discovered external config: ${configPath}`);
19
+ console.log(`Found and merged in external config: ${configPath}`);
20
20
  try {
21
21
  const externalModule = require(configPath);
22
22
  const externalConfig = externalModule?.default ?? externalModule;
@@ -11,4 +11,5 @@ export declare function getGlobalDefines(platform: string, targetMode: string):
11
11
  __UI_USE_XML_PARSER__: boolean;
12
12
  __UI_USE_EXTERNAL_RENDERER__: boolean;
13
13
  __TEST__: boolean;
14
+ "process.env.NODE_ENV": string;
14
15
  };
@@ -14,5 +14,7 @@ export function getGlobalDefines(platform, targetMode) {
14
14
  __UI_USE_EXTERNAL_RENDERER__: false,
15
15
  // various ecosystems use this global (react for example)
16
16
  __TEST__: false,
17
+ // Critical for various integrations (e.g. Vue only includes hmr runtime on this conditions)
18
+ "process.env.NODE_ENV": JSON.stringify(targetMode === "development" ? "development" : "production"),
17
19
  };
18
20
  }
@@ -0,0 +1 @@
1
+ export declare function embedMainEntryHMRForFlavor(flavor: string): string;
@@ -0,0 +1,18 @@
1
+ export function embedMainEntryHMRForFlavor(flavor) {
2
+ let imports = "";
3
+ switch (flavor) {
4
+ case "vue":
5
+ // Load HMR client for WebSocket connection to Vite dev server
6
+ imports += "import 'virtual:hmr-vue';\n";
7
+ imports +=
8
+ "console.info('@nativescript/vite HMR Vue client loaded.');\n";
9
+ break;
10
+ case "react":
11
+ break;
12
+ case "angular":
13
+ break;
14
+ case "solid":
15
+ break;
16
+ }
17
+ return imports;
18
+ }
@@ -1,5 +1,5 @@
1
1
  export declare function mainEntryPlugin(cliFlags: any, debug?: boolean, platform?: "ios" | "android" | "visionos"): {
2
2
  name: string;
3
- resolveId(id: any): string;
4
- load(id: any): string;
3
+ resolveId(id: string): string;
4
+ load(id: string): string;
5
5
  };
@@ -1,118 +1,82 @@
1
1
  import { getPackageJson, getProjectFilePath, getProjectRootPath, } from "./project.js";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
+ import { determineProjectFlavor } from "./flavor.js";
5
+ import { embedMainEntryHMRForFlavor } from "./main-entry-hmr-includes.js";
4
6
  const projectRoot = getProjectRootPath();
5
7
  // main entry
6
8
  const packageJson = getPackageJson();
7
9
  const mainEntry = getProjectFilePath(packageJson.main);
8
- // console.log("mainEntry:", mainEntry);
9
- // hmr client
10
- const hmrClientPath = getProjectFilePath("./node_modules/@nativescript/vite/dist/hmr/hmr-client.js");
11
- const hmrClientExists = fs.existsSync(hmrClientPath);
12
- // console.log("hmrClientPath:", hmrClientPath);
13
- // console.log("hmrClientExists:", hmrClientExists);
10
+ const flavor = determineProjectFlavor();
14
11
  // Check if polyfills file exists
15
12
  const polyfillsPath = getProjectFilePath("src/polyfills.ts");
16
13
  const polyfillsExists = fs.existsSync(polyfillsPath);
17
- // console.log("polyfillsPath:", polyfillsPath);
18
- // console.log("polyfillsExists:", polyfillsExists);
19
14
  const VIRTUAL_ID = "virtual:entry-with-polyfills";
20
15
  const RESOLVED = "\0" + VIRTUAL_ID;
21
16
  export function mainEntryPlugin(cliFlags, debug, platform) {
17
+ const HMR_ACTIVE = debug && !!cliFlags.hmr;
22
18
  return {
23
19
  name: "main-entry",
24
20
  resolveId(id) {
25
- if (id === VIRTUAL_ID) {
21
+ if (id === VIRTUAL_ID)
26
22
  return RESOLVED;
27
- }
28
23
  return null;
29
24
  },
30
25
  load(id) {
31
- if (id === RESOLVED) {
32
- let imports = "";
33
- // Align with webpack entry order: core globals and bundle entry points first
34
- imports += `import '@nativescript/core/globals/index';\n`;
35
- // // explicit extension helps some bundlers to retain side effects
36
- imports += `import '@nativescript/core/bundle-entry-points';\n`;
37
- // Ensure Android app components are included
38
- if (platform === "android") {
39
- // Import explicit Android variants with extension to avoid resolution ambiguity
40
- imports += `import * as __ns_android_frame from '@nativescript/core/ui/frame/index.android.js?ns-keep';\n`;
41
- imports += `import * as __ns_android_activity from '@nativescript/core/ui/frame/activity.android.js?ns-keep';\n`;
42
- // Reference bindings to keep the modules in the graph even if they only have side effects
43
- imports += `void __ns_android_frame; void __ns_android_activity;\n`;
44
- // This may still be needed - needs more testing
45
- // Ensure commonly tree-shaken Android UI modules are included so SBG
46
- // discovers their Java listener/impl classes. Keep imports minimal but
47
- // comprehensive across the missing bindings list.
48
- // const __ns_android_modules = [
49
- // "@nativescript/core/application",
50
- // "@nativescript/core/text",
51
- // "@nativescript/core/timer",
52
- // "@nativescript/core/utils",
53
- // "@nativescript/core/ui/gestures",
54
- // "@nativescript/core/ui/action-bar",
55
- // "@nativescript/core/ui/dialogs",
56
- // "@nativescript/core/ui/list-view",
57
- // "@nativescript/core/ui/search-bar",
58
- // "@nativescript/core/ui/tab-view",
59
- // "@nativescript/core/ui/web-view",
60
- // "@nativescript/core/ui/slider",
61
- // "@nativescript/core/ui/switch",
62
- // "@nativescript/core/ui/transition",
63
- // "@nativescript/core/ui/date-picker",
64
- // "@nativescript/core/ui/time-picker",
65
- // "@nativescript/core/ui/image",
66
- // "@nativescript/core/ui/image-cache",
67
- // "@nativescript/core/ui/text-base",
68
- // "@nativescript/core/ui/label",
69
- // "@nativescript/core/ui/text-field",
70
- // "@nativescript/core/ui/text-view",
71
- // "@nativescript/core/text/span",
72
- // "@nativescript/core/text/formatted-string",
73
- // "@nativescript/core/ui/animation",
74
- // "@nativescript/core/ui/layouts/layout-base",
75
- // ];
76
- // for (const m of __ns_android_modules) {
77
- // imports += `import '${m}?ns-keep';\n`;
78
- // }
79
- }
80
- if (polyfillsExists) {
81
- imports += `import '${polyfillsPath}';\n`;
82
- }
83
- // Import CSS and apply via Application.addCss before main entry
84
- const appCssPath = path.resolve(projectRoot, "src/app.css");
85
- if (fs.existsSync(appCssPath)) {
86
- imports += `
87
- // Import and apply global CSS before Angular bootstrap
88
- import appCssContent from './src/app.css?inline';
89
- import { Application } from '@nativescript/core';
90
-
91
- if (appCssContent) {
92
- try {
93
- Application.addCss(appCssContent);
94
- // console.log('🎨 Global CSS applied');
95
- } catch (error) {
96
- console.error('Error applying CSS:', error);
97
- }
98
- }`;
99
- }
100
- // Import main entry to initialize after all platform setup above
101
- imports += `import '${mainEntry}';\n`;
102
- // Import WebSocket support for HMR in development
103
- if (debug && cliFlags.hmr && hmrClientExists) {
104
- imports += `import '${hmrClientPath}';\n`;
105
- }
106
- // Import inspector modules for debugging in development
107
- if (debug) {
108
- imports += `import '@nativescript/core/inspector_modules';\n`;
109
- }
110
- // if (debug) {
111
- // console.log("🔄 Virtual entry imports:", imports);
112
- // }
113
- return imports;
26
+ if (id !== RESOLVED)
27
+ return null;
28
+ let imports = "";
29
+ // Align with webpack entry order: core globals and bundle entry points first
30
+ imports += "import '@nativescript/core/globals/index';\n";
31
+ // explicit extension helps some bundlers to retain side effects
32
+ imports += "import '@nativescript/core/bundle-entry-points';\n";
33
+ // Ensure Android app components are included
34
+ if (platform === "android") {
35
+ // Import explicit Android variants with extension to avoid resolution ambiguity
36
+ imports +=
37
+ "import * as __ns_android_frame from '@nativescript/core/ui/frame/index.android.js?ns-keep';\n";
38
+ imports +=
39
+ "import * as __ns_android_activity from '@nativescript/core/ui/frame/activity.android.js?ns-keep';\n";
40
+ // Reference bindings to keep the modules in the graph even if they only have side effects
41
+ imports += "void __ns_android_frame; void __ns_android_activity;\n";
114
42
  }
115
- return null;
43
+ if (polyfillsExists) {
44
+ imports += `import '${polyfillsPath}';\n`;
45
+ imports += `if (__NS_ENV_VERBOSE__) console.info('[ns-entry] polyfills imported from', ${polyfillsPath});\n`;
46
+ }
47
+ else {
48
+ imports += "if (__NS_ENV_VERBOSE__) console.info('[ns-entry] no polyfills file found');\n";
49
+ }
50
+ if (HMR_ACTIVE) {
51
+ // Ensure WebSocket polyfill is loaded early for device runtime
52
+ imports += "import '@valor/nativescript-websockets';\n";
53
+ imports += "if (__NS_ENV_VERBOSE__) console.info('[ns-entry] websockets polyfill imported');\n";
54
+ }
55
+ // Import CSS and apply via Application.addCss before main entry
56
+ const appCssPath = path.resolve(projectRoot, "src/app.css");
57
+ if (fs.existsSync(appCssPath)) {
58
+ imports += `
59
+ // Import and apply global CSS before app bootstrap
60
+ import appCssContent from './src/app.css?inline';
61
+ import { Application } from '@nativescript/core';
62
+ if (appCssContent) {
63
+ try { Application.addCss(appCssContent); } catch (error) { console.error('Error applying CSS:', error); }
64
+ }
65
+ `;
66
+ }
67
+ // Import the main entry file
68
+ imports += `if (__NS_ENV_VERBOSE__) console.info('[ns-entry] Importing main entry', '${mainEntry}');\n`;
69
+ imports += `import '${mainEntry}';\n`;
70
+ if (HMR_ACTIVE) {
71
+ // Start HMR client after app boots
72
+ imports += embedMainEntryHMRForFlavor(flavor);
73
+ }
74
+ // Import inspector modules for debugging in development
75
+ if (debug) {
76
+ imports += "import '@nativescript/core/inspector_modules';\n";
77
+ imports += "if (__NS_ENV_VERBOSE__) console.info('[ns-entry] inspector modules imported');\n";
78
+ }
79
+ return imports;
116
80
  },
117
81
  };
118
82
  }
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from "vite";
2
+ export declare function moduleRunnerPatchPlugin(): Plugin;
3
+ export default moduleRunnerPatchPlugin;
@@ -0,0 +1,65 @@
1
+ // Build-time patch: ensure vendor.mjs's bundled ModuleRunner.getModuleInformation
2
+ // always receives a valid options object with a cache to prevent
3
+ // "Cannot use 'in' operator to search for 'cache' in undefined".
4
+ export function moduleRunnerPatchPlugin() {
5
+ return {
6
+ name: "ns-module-runner-patch",
7
+ apply: "build",
8
+ enforce: "post",
9
+ generateBundle(_opts, bundle) {
10
+ for (const [fileName, chunk] of Object.entries(bundle)) {
11
+ if (fileName !== "vendor.mjs")
12
+ continue;
13
+ if (chunk.type !== "chunk" || typeof chunk.code !== "string")
14
+ continue;
15
+ let code = chunk.code;
16
+ // Try to locate the function definition (non-minified dev build keeps names)
17
+ // Handle both forms: function getModuleInformation(id, options) { ... }
18
+ // and class method or object method: getModuleInformation(id, options) { ... }
19
+ const patterns = [
20
+ /function\s+getModuleInformation\s*\(([^)]*)\)\s*\{/,
21
+ /getModuleInformation\s*\(([^)]*)\)\s*\{/,
22
+ ];
23
+ let replaced = false;
24
+ for (const re of patterns) {
25
+ const m = re.exec(code);
26
+ if (!m)
27
+ continue;
28
+ const rawParams = (m[1] || "")
29
+ .split(",")
30
+ .map((s) => s.trim())
31
+ .filter(Boolean);
32
+ const idParam = rawParams[0];
33
+ const second = rawParams[1];
34
+ const third = rawParams[2];
35
+ let guard = "\n";
36
+ if (third && second) {
37
+ // Signature: (id, importer, options)
38
+ guard += `if (typeof ${second} !== 'string') ${second} = undefined;\n`;
39
+ guard += `${third} = ${third} && typeof ${third}==='object' ? ${third} : {};\n`;
40
+ guard += `if (!('cache' in ${third})) ${third}.cache = new Map();\n`;
41
+ }
42
+ else if (second) {
43
+ // Signature: (id, options)
44
+ guard += `${second} = ${second} && typeof ${second}==='object' ? ${second} : {};\n`;
45
+ guard += `if (!('cache' in ${second})) ${second}.cache = new Map();\n`;
46
+ }
47
+ else {
48
+ // Unknown/minified: use arguments[] positions
49
+ guard += `(function(){ try{ var __imp = arguments[1]; if (typeof __imp !== 'string') arguments[1] = undefined; } catch(_){} })();\n`;
50
+ guard += `(function(){ try{ var __o = arguments[2] ?? arguments[1]; if (!__o || typeof __o!=='object') { __o = {}; if (arguments.length>2) arguments[2]=__o; else arguments[1]=__o; } if (!('cache' in __o)) __o.cache = new Map(); } catch(_){} })();\n`;
51
+ }
52
+ // Inject guard right after the opening brace of the function
53
+ const start = m.index + m[0].length;
54
+ code = code.slice(0, start) + guard + code.slice(start);
55
+ replaced = true;
56
+ break;
57
+ }
58
+ if (replaced) {
59
+ chunk.code = code;
60
+ }
61
+ }
62
+ },
63
+ };
64
+ }
65
+ export default moduleRunnerPatchPlugin;
@@ -1,21 +1,8 @@
1
- export declare function hmrPlugin(targetMode: string): {
2
- name: string;
3
- buildStart(): void;
4
- watchChange(id: any, { event }: {
5
- event: any;
6
- }): void;
7
- handleHotUpdate({ file, server, timestamp }: {
8
- file: any;
9
- server: any;
10
- timestamp: any;
11
- }): any[];
12
- };
13
- export declare function cliPlugin(targetMode: string, cliFlags: any): {
1
+ export declare function cliPlugin(distOutputFolder: string, isDevMode: boolean, verboseLogs: boolean, hmrActive: boolean): {
14
2
  name: string;
15
3
  apply: string;
16
4
  enforce: "post";
17
5
  configResolved(config: any): void;
18
- buildStart(): void;
19
6
  generateBundle(options: any, bundle: any): void;
20
7
  writeBundle(options: any, bundle: any): void;
21
8
  closeBundle(): void;