@nativescript/vite 0.0.1-alpha.1 → 0.0.1-alpha.3
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 +135 -37
- 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 +59 -95
- 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 +1 -14
- package/dist/helpers/ns-cli-plugins.js +54 -107
- package/dist/helpers/package-platform-aliases.d.ts +1 -1
- package/dist/helpers/package-platform-aliases.js +4 -4
- package/dist/helpers/ts-config-paths.d.ts +1 -1
- package/dist/helpers/ts-config-paths.js +3 -3
- 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/helpers/side-effects.d.ts +0 -14
- package/dist/helpers/side-effects.js +0 -69
- 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,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 {
|
|
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
|
-
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
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,
|
|
@@ -169,7 +234,7 @@ export const baseConfig = ({ mode }) => {
|
|
|
169
234
|
nsConfigAsJsonPlugin(),
|
|
170
235
|
NativeScriptPlugin({ platform }),
|
|
171
236
|
// Ensure globals and Android activity are included early via virtual entry
|
|
172
|
-
mainEntryPlugin(
|
|
237
|
+
mainEntryPlugin(platform, verboseLogs, hmrActive),
|
|
173
238
|
dynamicImportPlugin(),
|
|
174
239
|
// Transform Vite worker URLs to NativeScript format AFTER bundling
|
|
175
240
|
workerUrlPlugin(),
|
|
@@ -182,22 +247,35 @@ export const baseConfig = ({ mode }) => {
|
|
|
182
247
|
}),
|
|
183
248
|
]
|
|
184
249
|
: []),
|
|
185
|
-
// NativeScript
|
|
186
|
-
|
|
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:
|
|
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
|
-
|
|
198
|
-
|
|
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
|
-
//
|
|
222
|
-
sourcemap:
|
|
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
|
-
...(
|
|
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",
|
|
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(`
|
|
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(
|
|
1
|
+
export declare function mainEntryPlugin(platform: "ios" | "android" | "visionos", verboseLogs: boolean, hmrActive: boolean): {
|
|
2
2
|
name: string;
|
|
3
|
-
resolveId(id:
|
|
4
|
-
load(id:
|
|
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
|
-
|
|
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
|
-
export function mainEntryPlugin(
|
|
16
|
+
export function mainEntryPlugin(platform, verboseLogs, hmrActive) {
|
|
22
17
|
return {
|
|
23
18
|
name: "main-entry",
|
|
24
19
|
resolveId(id) {
|
|
25
|
-
if (id === VIRTUAL_ID)
|
|
20
|
+
if (id === VIRTUAL_ID)
|
|
26
21
|
return RESOLVED;
|
|
27
|
-
}
|
|
28
22
|
return null;
|
|
29
23
|
},
|
|
30
24
|
load(id) {
|
|
31
|
-
if (id
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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;
|
|
25
|
+
if (id !== RESOLVED)
|
|
26
|
+
return null;
|
|
27
|
+
let imports = "";
|
|
28
|
+
// Align with webpack entry order: core globals and bundle entry points first
|
|
29
|
+
imports += "import '@nativescript/core/globals/index';\n";
|
|
30
|
+
// explicit extension helps some bundlers to retain side effects
|
|
31
|
+
imports += "import '@nativescript/core/bundle-entry-points';\n";
|
|
32
|
+
// Ensure Android app components are included
|
|
33
|
+
if (platform === "android") {
|
|
34
|
+
// Import explicit Android variants with extension to avoid resolution ambiguity
|
|
35
|
+
imports +=
|
|
36
|
+
"import * as __ns_android_frame from '@nativescript/core/ui/frame/index.android.js?ns-keep';\n";
|
|
37
|
+
imports +=
|
|
38
|
+
"import * as __ns_android_activity from '@nativescript/core/ui/frame/activity.android.js?ns-keep';\n";
|
|
39
|
+
// Reference bindings to keep the modules in the graph even if they only have side effects
|
|
40
|
+
imports += "void __ns_android_frame; void __ns_android_activity;\n";
|
|
114
41
|
}
|
|
115
|
-
|
|
42
|
+
if (polyfillsExists) {
|
|
43
|
+
imports += `import '${polyfillsPath}';\n`;
|
|
44
|
+
// Ensure path is emitted as a proper JS string literal
|
|
45
|
+
imports += `if (__NS_ENV_VERBOSE__) console.info('[ns-entry] polyfills imported from', ${JSON.stringify(polyfillsPath)});\n`;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
imports += "if (__NS_ENV_VERBOSE__) console.info('[ns-entry] no polyfills file found');\n";
|
|
49
|
+
}
|
|
50
|
+
if (hmrActive) {
|
|
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 (hmrActive) {
|
|
71
|
+
// Start HMR client after app boots
|
|
72
|
+
imports += embedMainEntryHMRForFlavor(flavor);
|
|
73
|
+
}
|
|
74
|
+
// Import inspector modules for debugging in development
|
|
75
|
+
if (verboseLogs) {
|
|
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,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
|
|
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;
|