@nativescript/vite 0.0.1-alpha.0 → 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.
- package/dist/configuration/base.js +178 -71
- package/dist/helpers/external-configs.js +1 -1
- package/dist/helpers/global-defines.d.ts +1 -0
- package/dist/helpers/global-defines.js +2 -0
- package/dist/helpers/main-entry-hmr-includes.d.ts +1 -0
- package/dist/helpers/main-entry-hmr-includes.js +18 -0
- package/dist/helpers/main-entry.d.ts +3 -3
- package/dist/helpers/main-entry.js +61 -54
- package/dist/helpers/module-runner-patch.d.ts +3 -0
- package/dist/helpers/module-runner-patch.js +65 -0
- package/dist/helpers/ns-cli-plugins.d.ts +4 -14
- package/dist/helpers/ns-cli-plugins.js +124 -101
- package/dist/helpers/package-platform-aliases.d.ts +1 -1
- package/dist/helpers/package-platform-aliases.js +4 -4
- package/dist/helpers/preserve-imports.d.ts +2 -0
- package/dist/helpers/preserve-imports.js +19 -0
- package/dist/helpers/ts-config-paths.d.ts +1 -1
- package/dist/helpers/ts-config-paths.js +6 -4
- package/dist/hmr/client-vue.d.ts +6 -0
- package/dist/hmr/client-vue.js +563 -0
- package/dist/hmr/component-tracker.d.ts +23 -0
- package/dist/hmr/component-tracker.js +193 -0
- package/dist/hmr/css-handler.d.ts +4 -0
- package/dist/hmr/css-handler.js +77 -0
- package/dist/hmr/message-handler.d.ts +1 -0
- package/dist/hmr/message-handler.js +590 -0
- package/dist/hmr/nsv-hooks.d.ts +2 -0
- package/dist/hmr/nsv-hooks.js +481 -0
- package/dist/hmr/plugin-vue.d.ts +2 -0
- package/dist/hmr/plugin-vue.js +38 -0
- package/dist/hmr/plugins/index.d.ts +1 -0
- package/dist/hmr/plugins/index.js +16 -0
- package/dist/hmr/plugins/plugin-vue.d.ts +2 -0
- package/dist/hmr/plugins/plugin-vue.js +41 -0
- package/dist/hmr/plugins/websocket-vue.d.ts +2 -0
- package/dist/hmr/plugins/websocket-vue.js +882 -0
- package/dist/hmr/runtime-vue.d.ts +13 -0
- package/dist/hmr/runtime-vue.js +2306 -0
- package/dist/hmr/types.d.ts +24 -0
- package/dist/hmr/types.js +2 -0
- package/dist/hmr/websocket-vue.d.ts +2 -0
- package/dist/hmr/websocket-vue.js +875 -0
- package/dist/shims/node-module.d.ts +5 -0
- package/dist/shims/node-module.js +12 -0
- package/package.json +2 -1
- package/dist/configuration/old-without-merge-base.d.ts +0 -13
- package/dist/configuration/old-without-merge-base.js +0 -249
- package/dist/hmr/hmr-angular.d.ts +0 -1
- package/dist/hmr/hmr-angular.js +0 -34
- package/dist/hmr/hmr-bridge.d.ts +0 -18
- package/dist/hmr/hmr-bridge.js +0 -154
- package/dist/hmr/hmr-client.d.ts +0 -5
- package/dist/hmr/hmr-client.js +0 -93
- package/dist/hmr/hmr-server.d.ts +0 -20
- 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,12 +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 {
|
|
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";
|
|
24
|
+
import { preserveImportsPlugin } from "../helpers/preserve-imports.js";
|
|
21
25
|
import { externalConfigMerges, applyExternalConfigs, } from "../helpers/external-configs.js";
|
|
22
|
-
|
|
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";
|
|
23
32
|
const projectRoot = getProjectRootPath();
|
|
24
33
|
/**
|
|
25
34
|
* Plugins can define nativescript.vite.mjs
|
|
@@ -27,8 +36,7 @@ const projectRoot = getProjectRootPath();
|
|
|
27
36
|
*/
|
|
28
37
|
applyExternalConfigs();
|
|
29
38
|
export const baseConfig = ({ mode }) => {
|
|
30
|
-
const
|
|
31
|
-
const targetMode = process.env.production ? "production" : "development";
|
|
39
|
+
const targetMode = mode === "development" ? "development" : "production";
|
|
32
40
|
const cliArgs = minimist(process.argv.slice(2), { "--": true });
|
|
33
41
|
const cliFlags = (cliArgs["--"] || []).reduce((obj, flag) => {
|
|
34
42
|
// remove env prefix
|
|
@@ -36,20 +44,67 @@ export const baseConfig = ({ mode }) => {
|
|
|
36
44
|
obj[rawKey] = rest.length === 0 ? true : rest.join("=");
|
|
37
45
|
return obj;
|
|
38
46
|
}, {});
|
|
39
|
-
console.log("cliFlags:", cliFlags);
|
|
40
|
-
const
|
|
47
|
+
// console.log("cliFlags:", cliFlags);
|
|
48
|
+
const isDevMode = targetMode === "development";
|
|
49
|
+
const debug = !!process.env.DEBUG || isDevMode;
|
|
50
|
+
const hmrActive = isDevMode && !!cliFlags.hmr;
|
|
51
|
+
const platform = cliFlags.platform || "ios";
|
|
41
52
|
if (debug) {
|
|
42
53
|
console.log("--------------");
|
|
43
|
-
console.log("Vite config mode:", mode);
|
|
54
|
+
// console.log("Vite config mode:", mode);
|
|
44
55
|
console.log("Target mode:", targetMode);
|
|
45
56
|
console.log("Platform:", platform);
|
|
57
|
+
console.log("HMR active:", hmrActive);
|
|
46
58
|
console.log("--------------");
|
|
47
59
|
}
|
|
48
60
|
const flavor = determineProjectFlavor();
|
|
49
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
|
+
};
|
|
50
86
|
// Create TypeScript aliases with platform support
|
|
51
|
-
const tsConfigData = getTsConfigData(
|
|
87
|
+
const tsConfigData = getTsConfigData(verboseLogs, platform);
|
|
52
88
|
// Common resolve configuration for both main and worker builds
|
|
89
|
+
// Build platform-aware extension preference order and exclude the opposite platform
|
|
90
|
+
const platformExtensions = (() => {
|
|
91
|
+
const base = [".tsx", ".jsx", ".ts", ".js"];
|
|
92
|
+
const exts = [];
|
|
93
|
+
if (platform === "android") {
|
|
94
|
+
exts.push(".android.tsx", ".tsx", ".android.jsx", ".jsx", ".android.ts", ".ts", ".android.js", ".js");
|
|
95
|
+
}
|
|
96
|
+
else if (platform === "ios" || platform === "visionos") {
|
|
97
|
+
// Treat visionOS like iOS for file resolution
|
|
98
|
+
exts.push(".ios.tsx", ".tsx", ".ios.jsx", ".jsx", ".ios.ts", ".ts", ".ios.js", ".js");
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// Fallback: no platform-specific preference
|
|
102
|
+
exts.push(...base);
|
|
103
|
+
}
|
|
104
|
+
// Always allow these last
|
|
105
|
+
exts.push(".mjs", ".json");
|
|
106
|
+
return exts;
|
|
107
|
+
})();
|
|
53
108
|
const resolveConfig = {
|
|
54
109
|
// ensures Vite prefers ESM entry‑points
|
|
55
110
|
mainFields: ["module", "main"],
|
|
@@ -59,36 +114,31 @@ export const baseConfig = ({ mode }) => {
|
|
|
59
114
|
dedupe: ["@nativescript/core", "nativescript-vue", "vue"],
|
|
60
115
|
// Alias "@" and "~" to your src directory for cleaner imports
|
|
61
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
|
+
],
|
|
62
129
|
...aliasCssTree,
|
|
63
130
|
// 1) Catch exactly `~/package.json` → virtual module (MUST be first!)
|
|
64
131
|
{ find: /^~\/package\.json$/, replacement: "~/package.json" },
|
|
65
132
|
// TypeScript path aliases from tsconfig.json
|
|
66
133
|
...tsConfigData.aliases,
|
|
67
134
|
// Generic platform resolution for any npm package
|
|
68
|
-
packagePlatformAliases(tsConfigData, platform,
|
|
69
|
-
// skipCommonjsPackages,
|
|
70
|
-
debugViteLogs),
|
|
135
|
+
packagePlatformAliases(tsConfigData, platform, verboseLogs),
|
|
71
136
|
// 2) Catch everything else under "~/" → your src/
|
|
72
137
|
{ find: /^~\/(.*)$/, replacement: path.resolve(projectRoot, "src/$1") },
|
|
73
138
|
// optional: "@" → src/
|
|
74
139
|
{ find: "@", replacement: path.resolve(projectRoot, "src") },
|
|
75
140
|
],
|
|
76
|
-
extensions:
|
|
77
|
-
".ios.tsx",
|
|
78
|
-
".android.tsx",
|
|
79
|
-
".tsx",
|
|
80
|
-
".ios.jsx",
|
|
81
|
-
".android.jsx",
|
|
82
|
-
".jsx",
|
|
83
|
-
".ios.ts",
|
|
84
|
-
".android.ts",
|
|
85
|
-
".ts",
|
|
86
|
-
".ios.js",
|
|
87
|
-
".android.js",
|
|
88
|
-
".js",
|
|
89
|
-
".mjs",
|
|
90
|
-
".json",
|
|
91
|
-
],
|
|
141
|
+
extensions: platformExtensions,
|
|
92
142
|
preserveSymlinks: true,
|
|
93
143
|
};
|
|
94
144
|
// Common define configuration for both main and worker builds
|
|
@@ -112,21 +162,20 @@ export const baseConfig = ({ mode }) => {
|
|
|
112
162
|
staticCopyTargets.push({ src: `${fontsAppDir}/**/*`, dest: "fonts" });
|
|
113
163
|
}
|
|
114
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,
|
|
115
169
|
resolve: resolveConfig,
|
|
116
|
-
|
|
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
|
+
},
|
|
117
175
|
// Vite's built-in solution for CommonJS/ESM compatibility issues
|
|
118
176
|
optimizeDeps: {
|
|
119
177
|
// Force pre-bundling of problematic CommonJS packages
|
|
120
|
-
include: [
|
|
121
|
-
// "source-map-js",
|
|
122
|
-
"@valor/nativescript-websockets",
|
|
123
|
-
// React and related packages for proper module resolution
|
|
124
|
-
"react",
|
|
125
|
-
"react-reconciler",
|
|
126
|
-
"react-nativescript",
|
|
127
|
-
// ...(optimizeDeps || []),
|
|
128
|
-
// Add any other problematic packages here
|
|
129
|
-
],
|
|
178
|
+
include: [],
|
|
130
179
|
// Handle Node.js built-ins and other edge cases
|
|
131
180
|
esbuildOptions: {
|
|
132
181
|
// Pass the same conditions to ESBuild for css-tree compatibility
|
|
@@ -134,10 +183,39 @@ export const baseConfig = ({ mode }) => {
|
|
|
134
183
|
// Define globals for Node.js built-ins if needed
|
|
135
184
|
define: {
|
|
136
185
|
global: "globalThis",
|
|
186
|
+
"process.env.NODE_ENV": JSON.stringify(debug ? "development" : "production"),
|
|
137
187
|
},
|
|
138
188
|
},
|
|
189
|
+
// Avoid pre-bundling NativeScript core to prevent esbuild from stripping side-effectful modules
|
|
190
|
+
exclude: [
|
|
191
|
+
"@nativescript/core",
|
|
192
|
+
"@nativescript/core/ui/frame",
|
|
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",
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
esbuild: {
|
|
204
|
+
define: {
|
|
205
|
+
"process.env.NODE_ENV": JSON.stringify(debug ? "development" : "production"),
|
|
206
|
+
},
|
|
139
207
|
},
|
|
140
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
|
+
}),
|
|
215
|
+
// Ensure explicit keep markers are honored
|
|
216
|
+
preserveImportsPlugin(),
|
|
217
|
+
// Vue HMR plugins for development mode
|
|
218
|
+
...(hmrActive ? getHMRPlugins(platform, flavor, verboseLogs) : []),
|
|
141
219
|
// TODO: make flavor plugins dynamic
|
|
142
220
|
// ...flavorPlugins,
|
|
143
221
|
...commonjsPlugins,
|
|
@@ -151,14 +229,12 @@ export const baseConfig = ({ mode }) => {
|
|
|
151
229
|
defaultIsModuleExports: "auto",
|
|
152
230
|
transformMixedEsModules: true,
|
|
153
231
|
// Ignore optional dependencies that are meant to fail gracefully
|
|
154
|
-
ignore: [
|
|
155
|
-
"@nativescript/android",
|
|
156
|
-
"@nativescript/ios",
|
|
157
|
-
],
|
|
232
|
+
ignore: ["@nativescript/android", "@nativescript/ios"],
|
|
158
233
|
}),
|
|
159
234
|
nsConfigAsJsonPlugin(),
|
|
160
235
|
NativeScriptPlugin({ platform }),
|
|
161
|
-
|
|
236
|
+
// Ensure globals and Android activity are included early via virtual entry
|
|
237
|
+
mainEntryPlugin(cliFlags, debug, platform),
|
|
162
238
|
dynamicImportPlugin(),
|
|
163
239
|
// Transform Vite worker URLs to NativeScript format AFTER bundling
|
|
164
240
|
workerUrlPlugin(),
|
|
@@ -171,22 +247,35 @@ export const baseConfig = ({ mode }) => {
|
|
|
171
247
|
}),
|
|
172
248
|
]
|
|
173
249
|
: []),
|
|
174
|
-
// NativeScript
|
|
175
|
-
|
|
176
|
-
// NativeScript CLI integration - enhanced IPC communication for HMR
|
|
177
|
-
cliPlugin(targetMode, cliFlags),
|
|
250
|
+
// NativeScript CLI integration
|
|
251
|
+
cliPlugin(distOutputFolder, isDevMode, verboseLogs, hmrActive),
|
|
178
252
|
],
|
|
179
253
|
css: {
|
|
180
254
|
postcss: "./postcss.config.js",
|
|
181
255
|
},
|
|
182
256
|
// Development server configuration for HMR
|
|
183
|
-
server:
|
|
257
|
+
server: isDevMode
|
|
184
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)
|
|
185
275
|
hmr: {
|
|
186
|
-
|
|
187
|
-
|
|
276
|
+
protocol: useHttps ? "wss" : "ws",
|
|
277
|
+
path: "/vite-hmr",
|
|
188
278
|
},
|
|
189
|
-
// CORS for development
|
|
190
279
|
cors: true,
|
|
191
280
|
}
|
|
192
281
|
: {},
|
|
@@ -204,15 +293,23 @@ export const baseConfig = ({ mode }) => {
|
|
|
204
293
|
},
|
|
205
294
|
},
|
|
206
295
|
build: {
|
|
296
|
+
// Ensure Vite and plugins (like vite-plugin-static-copy) use the same output directory
|
|
297
|
+
outDir: path.resolve(projectRoot, distOutputFolder),
|
|
207
298
|
target: "esnext",
|
|
208
299
|
minify: !debug,
|
|
209
300
|
// Generate source maps for debugging
|
|
210
|
-
//
|
|
211
|
-
sourcemap:
|
|
301
|
+
// External sourcemaps so DevTools loads small .mjs files and fetches maps on demand
|
|
302
|
+
sourcemap: debug,
|
|
212
303
|
// Disable module preloading to avoid browser APIs
|
|
213
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
|
+
}),
|
|
214
311
|
// Optimize for development speed
|
|
215
|
-
...(
|
|
312
|
+
...(isDevMode && {
|
|
216
313
|
// Faster builds in development
|
|
217
314
|
reportCompressedSize: false,
|
|
218
315
|
chunkSizeWarningLimit: 2000,
|
|
@@ -221,11 +318,19 @@ export const baseConfig = ({ mode }) => {
|
|
|
221
318
|
include: [/node_modules/],
|
|
222
319
|
},
|
|
223
320
|
rollupOptions: {
|
|
321
|
+
treeshake: {
|
|
322
|
+
// Preserve side effects for NativeScript core so classes/functions
|
|
323
|
+
// aren't tree-shaken out of vendor.mjs.
|
|
324
|
+
moduleSideEffects: (id) => /node_modules[\\\/]\@nativescript[\\\/]core[\\\/]/.test(id) || null,
|
|
325
|
+
},
|
|
224
326
|
input: "virtual:entry-with-polyfills",
|
|
225
327
|
output: {
|
|
226
|
-
dir: path.resolve(projectRoot, "dist"),
|
|
227
328
|
format: "es", // Emit ES modules (.mjs)
|
|
228
|
-
entryFileNames: "bundle.mjs",
|
|
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() + "/",
|
|
229
334
|
chunkFileNames: (chunk) => {
|
|
230
335
|
if (chunk.name === "vendor")
|
|
231
336
|
return "vendor.mjs";
|
|
@@ -239,25 +344,27 @@ export const baseConfig = ({ mode }) => {
|
|
|
239
344
|
// Create single vendor chunk - no separate globals chunk to avoid circular deps
|
|
240
345
|
manualChunks(id) {
|
|
241
346
|
if (id.includes("node_modules")) {
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
if
|
|
245
|
-
|
|
246
|
-
"@nativescript/angular"
|
|
247
|
-
"@nativescript/
|
|
248
|
-
"@valor/nativescript-websockets",
|
|
249
|
-
"make-error",
|
|
250
|
-
// "source-map-js",
|
|
251
|
-
"zone.js",
|
|
252
|
-
"/globals",
|
|
253
|
-
"/polyfills",
|
|
254
|
-
].includes(id)) {
|
|
347
|
+
// Keep common dependencies in the main bundle
|
|
348
|
+
// Very Important: keep Angular, NS Angular and core in main bundle to avoid issues with DI
|
|
349
|
+
// All flavors can do same if encounter ordering issues
|
|
350
|
+
if (id.includes("@angular/") ||
|
|
351
|
+
id.includes("@nativescript/angular") ||
|
|
352
|
+
id.includes("@nativescript/core")) {
|
|
255
353
|
return undefined; // Keep in main bundle
|
|
256
354
|
}
|
|
257
355
|
return "vendor";
|
|
258
356
|
}
|
|
259
357
|
},
|
|
260
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
|
+
: {}),
|
|
261
368
|
},
|
|
262
369
|
},
|
|
263
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(`
|
|
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;
|
|
@@ -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
|
-
export declare function mainEntryPlugin(cliFlags: any, debug?: boolean): {
|
|
1
|
+
export declare function mainEntryPlugin(cliFlags: any, debug?: boolean, platform?: "ios" | "android" | "visionos"): {
|
|
2
2
|
name: string;
|
|
3
|
-
resolveId(id:
|
|
4
|
-
load(id:
|
|
3
|
+
resolveId(id: string): string;
|
|
4
|
+
load(id: string): string;
|
|
5
5
|
};
|
|
@@ -1,75 +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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
export function mainEntryPlugin(cliFlags, debug) {
|
|
14
|
+
const VIRTUAL_ID = "virtual:entry-with-polyfills";
|
|
15
|
+
const RESOLVED = "\0" + VIRTUAL_ID;
|
|
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
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// Import
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
imports += `
|
|
48
|
-
// Import and apply global CSS
|
|
49
|
-
import appCssContent from './src/app.css?inline';
|
|
50
|
-
import { Application } from '@nativescript/core';
|
|
51
|
-
|
|
52
|
-
if (typeof global !== 'undefined' && appCssContent) {
|
|
53
|
-
try {
|
|
54
|
-
// Just testing logs if needed
|
|
55
|
-
// console.log('🎨 CSS content length:', appCssContent.length);
|
|
56
|
-
// console.log('🎨 CSS content preview:', appCssContent.substring(0, 200) + '...');
|
|
57
|
-
|
|
58
|
-
Application.addCss(appCssContent);
|
|
59
|
-
// console.log('🎨 Global CSS applied');
|
|
60
|
-
} catch (error) {
|
|
61
|
-
console.error('Error applying CSS:', error);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
`;
|
|
65
|
-
}
|
|
66
|
-
imports += `import '${mainEntry}';`;
|
|
67
|
-
if (debug) {
|
|
68
|
-
console.log("🔄 Virtual entry imports:", imports);
|
|
69
|
-
}
|
|
70
|
-
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";
|
|
71
42
|
}
|
|
72
|
-
|
|
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;
|
|
73
80
|
},
|
|
74
81
|
};
|
|
75
82
|
}
|
|
@@ -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;
|