@nativescript/vite 8.0.0-alpha.3 → 8.0.0-alpha.30

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 (295) hide show
  1. package/README.md +51 -11
  2. package/configuration/angular.d.ts +34 -1
  3. package/configuration/angular.js +369 -159
  4. package/configuration/angular.js.map +1 -1
  5. package/configuration/base.js +184 -14
  6. package/configuration/base.js.map +1 -1
  7. package/configuration/javascript.js +5 -72
  8. package/configuration/javascript.js.map +1 -1
  9. package/configuration/solid.js +27 -1
  10. package/configuration/solid.js.map +1 -1
  11. package/configuration/typescript.js +5 -75
  12. package/configuration/typescript.js.map +1 -1
  13. package/helpers/angular/angular-linker.d.ts +5 -6
  14. package/helpers/angular/angular-linker.js +36 -121
  15. package/helpers/angular/angular-linker.js.map +1 -1
  16. package/helpers/angular/inject-component-hmr-registration.d.ts +112 -0
  17. package/helpers/angular/inject-component-hmr-registration.js +291 -0
  18. package/helpers/angular/inject-component-hmr-registration.js.map +1 -0
  19. package/helpers/angular/inject-hmr-vite-ignore.d.ts +75 -0
  20. package/helpers/angular/inject-hmr-vite-ignore.js +221 -0
  21. package/helpers/angular/inject-hmr-vite-ignore.js.map +1 -0
  22. package/helpers/angular/inline-decorator-component-templates.js +1 -170
  23. package/helpers/angular/inline-decorator-component-templates.js.map +1 -1
  24. package/helpers/angular/js-lexer.d.ts +4 -0
  25. package/helpers/angular/js-lexer.js +182 -0
  26. package/helpers/angular/js-lexer.js.map +1 -0
  27. package/helpers/angular/shared-linker.d.ts +31 -3
  28. package/helpers/angular/shared-linker.js +67 -14
  29. package/helpers/angular/shared-linker.js.map +1 -1
  30. package/helpers/angular/synthesize-decorator-ctor-parameters.js +2 -170
  31. package/helpers/angular/synthesize-decorator-ctor-parameters.js.map +1 -1
  32. package/helpers/angular/synthesize-injectable-factories.js +1 -174
  33. package/helpers/angular/synthesize-injectable-factories.js.map +1 -1
  34. package/helpers/angular/util.d.ts +1 -0
  35. package/helpers/angular/util.js +88 -0
  36. package/helpers/angular/util.js.map +1 -1
  37. package/helpers/app-components.d.ts +2 -1
  38. package/helpers/app-components.js.map +1 -1
  39. package/helpers/app-css-state.d.ts +8 -0
  40. package/helpers/app-css-state.js +8 -0
  41. package/helpers/app-css-state.js.map +1 -0
  42. package/helpers/bundler-context.d.ts +11 -0
  43. package/helpers/bundler-context.js +71 -0
  44. package/helpers/bundler-context.js.map +1 -0
  45. package/helpers/config-as-json.js +10 -0
  46. package/helpers/config-as-json.js.map +1 -1
  47. package/helpers/dev-host.d.ts +341 -0
  48. package/helpers/dev-host.js +617 -0
  49. package/helpers/dev-host.js.map +1 -0
  50. package/helpers/esbuild-platform-resolver.js +4 -1
  51. package/helpers/esbuild-platform-resolver.js.map +1 -1
  52. package/helpers/global-defines.d.ts +51 -0
  53. package/helpers/global-defines.js +77 -0
  54. package/helpers/global-defines.js.map +1 -1
  55. package/helpers/hmr-scope.d.ts +26 -0
  56. package/helpers/hmr-scope.js +67 -0
  57. package/helpers/hmr-scope.js.map +1 -0
  58. package/helpers/init.js +0 -18
  59. package/helpers/init.js.map +1 -1
  60. package/helpers/logging.d.ts +1 -0
  61. package/helpers/logging.js +63 -3
  62. package/helpers/logging.js.map +1 -1
  63. package/helpers/main-entry.d.ts +2 -1
  64. package/helpers/main-entry.js +430 -47
  65. package/helpers/main-entry.js.map +1 -1
  66. package/helpers/nativeclass-esbuild-plugin.d.ts +2 -1
  67. package/helpers/nativeclass-esbuild-plugin.js.map +1 -1
  68. package/helpers/nativeclass-transform.js.map +1 -1
  69. package/helpers/nativeclass-transformer-plugin.d.ts +9 -2
  70. package/helpers/nativeclass-transformer-plugin.js +157 -14
  71. package/helpers/nativeclass-transformer-plugin.js.map +1 -1
  72. package/helpers/nativescript-package-resolver.js +8 -3
  73. package/helpers/nativescript-package-resolver.js.map +1 -1
  74. package/helpers/normalize-id.d.ts +42 -0
  75. package/helpers/normalize-id.js +60 -0
  76. package/helpers/normalize-id.js.map +1 -0
  77. package/helpers/ns-core-url.d.ts +88 -0
  78. package/helpers/ns-core-url.js +191 -0
  79. package/helpers/ns-core-url.js.map +1 -0
  80. package/helpers/package-platform-aliases.js +4 -3
  81. package/helpers/package-platform-aliases.js.map +1 -1
  82. package/helpers/platform-types.d.ts +2 -0
  83. package/helpers/platform-types.js +2 -0
  84. package/helpers/platform-types.js.map +1 -0
  85. package/helpers/prelink-angular.js +12 -33
  86. package/helpers/prelink-angular.js.map +1 -1
  87. package/helpers/project.d.ts +35 -0
  88. package/helpers/project.js +120 -2
  89. package/helpers/project.js.map +1 -1
  90. package/helpers/resolver.js +17 -2
  91. package/helpers/resolver.js.map +1 -1
  92. package/helpers/solid-jsx-deps.d.ts +15 -0
  93. package/helpers/solid-jsx-deps.js +178 -0
  94. package/helpers/solid-jsx-deps.js.map +1 -0
  95. package/helpers/ts-config-paths.d.ts +14 -0
  96. package/helpers/ts-config-paths.js +89 -8
  97. package/helpers/ts-config-paths.js.map +1 -1
  98. package/helpers/typescript-check.d.ts +2 -1
  99. package/helpers/typescript-check.js.map +1 -1
  100. package/helpers/workers.d.ts +20 -19
  101. package/helpers/workers.js +624 -4
  102. package/helpers/workers.js.map +1 -1
  103. package/hmr/client/css-handler.d.ts +1 -0
  104. package/hmr/client/css-handler.js +33 -20
  105. package/hmr/client/css-handler.js.map +1 -1
  106. package/hmr/client/css-update-overlay.d.ts +18 -0
  107. package/hmr/client/css-update-overlay.js +27 -0
  108. package/hmr/client/css-update-overlay.js.map +1 -0
  109. package/hmr/client/hmr-pending-overlay.d.ts +27 -0
  110. package/hmr/client/hmr-pending-overlay.js +50 -0
  111. package/hmr/client/hmr-pending-overlay.js.map +1 -0
  112. package/hmr/client/index.js +419 -15
  113. package/hmr/client/index.js.map +1 -1
  114. package/hmr/client/utils.d.ts +6 -1
  115. package/hmr/client/utils.js +184 -8
  116. package/hmr/client/utils.js.map +1 -1
  117. package/hmr/client/vue-sfc-update-overlay.d.ts +82 -0
  118. package/hmr/client/vue-sfc-update-overlay.js +133 -0
  119. package/hmr/client/vue-sfc-update-overlay.js.map +1 -0
  120. package/hmr/entry-runtime.d.ts +2 -1
  121. package/hmr/entry-runtime.js +252 -65
  122. package/hmr/entry-runtime.js.map +1 -1
  123. package/hmr/frameworks/angular/client/index.d.ts +1 -0
  124. package/hmr/frameworks/angular/client/index.js +778 -20
  125. package/hmr/frameworks/angular/client/index.js.map +1 -1
  126. package/hmr/frameworks/angular/server/linker.js +1 -4
  127. package/hmr/frameworks/angular/server/linker.js.map +1 -1
  128. package/hmr/frameworks/angular/server/strategy.js +13 -15
  129. package/hmr/frameworks/angular/server/strategy.js.map +1 -1
  130. package/hmr/frameworks/solid/server/strategy.js +3 -18
  131. package/hmr/frameworks/solid/server/strategy.js.map +1 -1
  132. package/hmr/frameworks/typescript/server/strategy.js +2 -15
  133. package/hmr/frameworks/typescript/server/strategy.js.map +1 -1
  134. package/hmr/frameworks/vue/client/index.js +30 -199
  135. package/hmr/frameworks/vue/client/index.js.map +1 -1
  136. package/hmr/helpers/ast-normalizer.js +52 -5
  137. package/hmr/helpers/ast-normalizer.js.map +1 -1
  138. package/hmr/helpers/cjs-named-exports.d.ts +23 -0
  139. package/hmr/helpers/cjs-named-exports.js +152 -0
  140. package/hmr/helpers/cjs-named-exports.js.map +1 -0
  141. package/hmr/helpers/package-exports.d.ts +16 -0
  142. package/hmr/helpers/package-exports.js +396 -0
  143. package/hmr/helpers/package-exports.js.map +1 -0
  144. package/hmr/server/angular-root-component.d.ts +79 -0
  145. package/hmr/server/angular-root-component.js +149 -0
  146. package/hmr/server/angular-root-component.js.map +1 -0
  147. package/hmr/server/constants.js +13 -4
  148. package/hmr/server/constants.js.map +1 -1
  149. package/hmr/server/core-sanitize.d.ts +90 -7
  150. package/hmr/server/core-sanitize.js +211 -56
  151. package/hmr/server/core-sanitize.js.map +1 -1
  152. package/hmr/server/framework-strategy.d.ts +9 -19
  153. package/hmr/server/hmr-module-graph.d.ts +37 -0
  154. package/hmr/server/hmr-module-graph.js +214 -0
  155. package/hmr/server/hmr-module-graph.js.map +1 -0
  156. package/hmr/server/import-map.js +60 -8
  157. package/hmr/server/import-map.js.map +1 -1
  158. package/hmr/server/index.js +1 -0
  159. package/hmr/server/index.js.map +1 -1
  160. package/hmr/server/ns-core-cjs-shape.d.ts +204 -0
  161. package/hmr/server/ns-core-cjs-shape.js +271 -0
  162. package/hmr/server/ns-core-cjs-shape.js.map +1 -0
  163. package/hmr/server/ns-rt-bridge.d.ts +51 -0
  164. package/hmr/server/ns-rt-bridge.js +131 -0
  165. package/hmr/server/ns-rt-bridge.js.map +1 -0
  166. package/hmr/server/ns-rt-route.d.ts +5 -0
  167. package/hmr/server/ns-rt-route.js +35 -0
  168. package/hmr/server/ns-rt-route.js.map +1 -0
  169. package/hmr/server/perf-instrumentation.d.ts +114 -0
  170. package/hmr/server/perf-instrumentation.js +195 -0
  171. package/hmr/server/perf-instrumentation.js.map +1 -0
  172. package/hmr/server/require-guard.d.ts +1 -0
  173. package/hmr/server/require-guard.js +12 -0
  174. package/hmr/server/require-guard.js.map +1 -0
  175. package/hmr/server/route-helpers.d.ts +7 -0
  176. package/hmr/server/route-helpers.js +13 -0
  177. package/hmr/server/route-helpers.js.map +1 -0
  178. package/hmr/server/server-origin.d.ts +12 -0
  179. package/hmr/server/server-origin.js +66 -0
  180. package/hmr/server/server-origin.js.map +1 -0
  181. package/hmr/server/shared-transform-request.js +12 -5
  182. package/hmr/server/shared-transform-request.js.map +1 -1
  183. package/hmr/server/vendor-bare-module-shims.d.ts +4 -0
  184. package/hmr/server/vendor-bare-module-shims.js +80 -0
  185. package/hmr/server/vendor-bare-module-shims.js.map +1 -0
  186. package/hmr/server/vite-plugin.js +60 -42
  187. package/hmr/server/vite-plugin.js.map +1 -1
  188. package/hmr/server/websocket-angular-entry.js +1 -1
  189. package/hmr/server/websocket-angular-entry.js.map +1 -1
  190. package/hmr/server/websocket-angular-hot-update.d.ts +17 -0
  191. package/hmr/server/websocket-angular-hot-update.js +176 -2
  192. package/hmr/server/websocket-angular-hot-update.js.map +1 -1
  193. package/hmr/server/websocket-core-bridge.d.ts +41 -6
  194. package/hmr/server/websocket-core-bridge.js +72 -75
  195. package/hmr/server/websocket-core-bridge.js.map +1 -1
  196. package/hmr/server/websocket-css-hot-update.d.ts +33 -0
  197. package/hmr/server/websocket-css-hot-update.js +65 -0
  198. package/hmr/server/websocket-css-hot-update.js.map +1 -0
  199. package/hmr/server/websocket-device-transform.d.ts +21 -0
  200. package/hmr/server/websocket-device-transform.js +1570 -0
  201. package/hmr/server/websocket-device-transform.js.map +1 -0
  202. package/hmr/server/websocket-graph-upsert.d.ts +15 -0
  203. package/hmr/server/websocket-graph-upsert.js +20 -0
  204. package/hmr/server/websocket-graph-upsert.js.map +1 -1
  205. package/hmr/server/websocket-hmr-pending.d.ts +43 -0
  206. package/hmr/server/websocket-hmr-pending.js +55 -0
  207. package/hmr/server/websocket-hmr-pending.js.map +1 -0
  208. package/hmr/server/websocket-hot-update.d.ts +51 -0
  209. package/hmr/server/websocket-hot-update.js +1160 -0
  210. package/hmr/server/websocket-hot-update.js.map +1 -0
  211. package/hmr/server/websocket-import-map-route.d.ts +15 -0
  212. package/hmr/server/websocket-import-map-route.js +44 -0
  213. package/hmr/server/websocket-import-map-route.js.map +1 -0
  214. package/hmr/server/websocket-module-bindings.js +3 -3
  215. package/hmr/server/websocket-module-bindings.js.map +1 -1
  216. package/hmr/server/websocket-module-specifiers.d.ts +66 -2
  217. package/hmr/server/websocket-module-specifiers.js +202 -19
  218. package/hmr/server/websocket-module-specifiers.js.map +1 -1
  219. package/hmr/server/websocket-ns-core.d.ts +21 -0
  220. package/hmr/server/websocket-ns-core.js +305 -0
  221. package/hmr/server/websocket-ns-core.js.map +1 -0
  222. package/hmr/server/websocket-ns-entry.d.ts +22 -0
  223. package/hmr/server/websocket-ns-entry.js +150 -0
  224. package/hmr/server/websocket-ns-entry.js.map +1 -0
  225. package/hmr/server/websocket-ns-m-paths.d.ts +3 -0
  226. package/hmr/server/websocket-ns-m-paths.js +92 -0
  227. package/hmr/server/websocket-ns-m-paths.js.map +1 -0
  228. package/hmr/server/websocket-ns-m-request.d.ts +45 -0
  229. package/hmr/server/websocket-ns-m-request.js +196 -0
  230. package/hmr/server/websocket-ns-m-request.js.map +1 -0
  231. package/hmr/server/websocket-ns-m.d.ts +34 -0
  232. package/hmr/server/websocket-ns-m.js +853 -0
  233. package/hmr/server/websocket-ns-m.js.map +1 -0
  234. package/hmr/server/websocket-served-module-helpers.d.ts +39 -0
  235. package/hmr/server/websocket-served-module-helpers.js +654 -0
  236. package/hmr/server/websocket-served-module-helpers.js.map +1 -0
  237. package/hmr/server/websocket-sfc.d.ts +24 -0
  238. package/hmr/server/websocket-sfc.js +1223 -0
  239. package/hmr/server/websocket-sfc.js.map +1 -0
  240. package/hmr/server/websocket-txn.d.ts +6 -0
  241. package/hmr/server/websocket-txn.js +39 -0
  242. package/hmr/server/websocket-txn.js.map +1 -0
  243. package/hmr/server/websocket-vendor-unifier.d.ts +10 -0
  244. package/hmr/server/websocket-vendor-unifier.js +45 -0
  245. package/hmr/server/websocket-vendor-unifier.js.map +1 -0
  246. package/hmr/server/websocket.d.ts +0 -30
  247. package/hmr/server/websocket.js +599 -6038
  248. package/hmr/server/websocket.js.map +1 -1
  249. package/hmr/shared/runtime/boot-placeholder-ui.d.ts +69 -0
  250. package/hmr/shared/runtime/boot-placeholder-ui.js +101 -0
  251. package/hmr/shared/runtime/boot-placeholder-ui.js.map +1 -0
  252. package/hmr/shared/runtime/boot-progress.d.ts +40 -0
  253. package/hmr/shared/runtime/boot-progress.js +128 -0
  254. package/hmr/shared/runtime/boot-progress.js.map +1 -0
  255. package/hmr/shared/runtime/boot-timeline.d.ts +18 -0
  256. package/hmr/shared/runtime/boot-timeline.js +52 -0
  257. package/hmr/shared/runtime/boot-timeline.js.map +1 -0
  258. package/hmr/shared/runtime/dev-overlay-snapshots.d.ts +31 -0
  259. package/hmr/shared/runtime/dev-overlay-snapshots.js +324 -0
  260. package/hmr/shared/runtime/dev-overlay-snapshots.js.map +1 -0
  261. package/hmr/shared/runtime/dev-overlay.d.ts +75 -26
  262. package/hmr/shared/runtime/dev-overlay.js +990 -260
  263. package/hmr/shared/runtime/dev-overlay.js.map +1 -1
  264. package/hmr/shared/runtime/module-provenance.js +1 -4
  265. package/hmr/shared/runtime/module-provenance.js.map +1 -1
  266. package/hmr/shared/runtime/root-placeholder-view.d.ts +19 -0
  267. package/hmr/shared/runtime/root-placeholder-view.js +310 -0
  268. package/hmr/shared/runtime/root-placeholder-view.js.map +1 -0
  269. package/hmr/shared/runtime/root-placeholder.js +352 -194
  270. package/hmr/shared/runtime/root-placeholder.js.map +1 -1
  271. package/hmr/shared/runtime/session-bootstrap.js +164 -1
  272. package/hmr/shared/runtime/session-bootstrap.js.map +1 -1
  273. package/hmr/shared/runtime/vendor-bootstrap.js +1 -9
  274. package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
  275. package/hmr/shared/vendor/manifest-collect.d.ts +32 -0
  276. package/hmr/shared/vendor/manifest-collect.js +512 -0
  277. package/hmr/shared/vendor/manifest-collect.js.map +1 -0
  278. package/hmr/shared/vendor/manifest-loader.d.ts +2 -1
  279. package/hmr/shared/vendor/manifest-loader.js +3 -2
  280. package/hmr/shared/vendor/manifest-loader.js.map +1 -1
  281. package/hmr/shared/vendor/manifest.d.ts +1 -5
  282. package/hmr/shared/vendor/manifest.js +102 -739
  283. package/hmr/shared/vendor/manifest.js.map +1 -1
  284. package/hmr/shared/vendor/vendor-device-shim.d.ts +1 -0
  285. package/hmr/shared/vendor/vendor-device-shim.js +208 -0
  286. package/hmr/shared/vendor/vendor-device-shim.js.map +1 -0
  287. package/hmr/shared/vendor/vendor-esbuild-plugins.d.ts +16 -0
  288. package/hmr/shared/vendor/vendor-esbuild-plugins.js +203 -0
  289. package/hmr/shared/vendor/vendor-esbuild-plugins.js.map +1 -0
  290. package/index.d.ts +1 -0
  291. package/index.js +5 -0
  292. package/index.js.map +1 -1
  293. package/package.json +55 -11
  294. package/runtime/core-aliases-early.js +17 -41
  295. package/runtime/core-aliases-early.js.map +1 -1
@@ -1,12 +1,12 @@
1
1
  import * as esbuild from 'esbuild';
2
- import { readFile } from 'fs/promises';
3
2
  import path from 'path';
4
- import { readFileSync } from 'fs';
5
3
  import { createHash } from 'crypto';
6
- import { createRequire } from 'node:module';
7
4
  import { registerVendorManifest, clearVendorManifest, getVendorManifest } from './registry.js';
5
+ import { collectVendorModules } from './manifest-collect.js';
8
6
  import { generatePlatformPolyfills } from '../runtime/platform-polyfills.js';
9
7
  import { createNativeClassEsbuildPlugin } from '../../../helpers/nativeclass-esbuild-plugin.js';
8
+ import { getGlobalDefines } from '../../../helpers/global-defines.js';
9
+ import { createVendorEsbuildPlugin, createSolidJsxEsbuildPlugin, angularLinkerEsbuildPlugin } from './vendor-esbuild-plugins.js';
10
10
  export const VENDOR_MANIFEST_ID = '@nativescript/vendor-manifest';
11
11
  export const VENDOR_MANIFEST_VIRTUAL_ID = '\0' + VENDOR_MANIFEST_ID;
12
12
  export const VENDOR_BUNDLE_ID = '@nativescript/vendor';
@@ -15,105 +15,6 @@ export const SERVER_VENDOR_PATH = '/@nativescript/vendor.mjs';
15
15
  export const SERVER_MANIFEST_PATH = '/@nativescript/vendor-manifest.json';
16
16
  export const DEFAULT_VENDOR_FILENAME = 'ns-vendor.mjs';
17
17
  export const DEFAULT_MANIFEST_FILENAME = 'ns-vendor-manifest.json';
18
- // Do not force-include @nativescript/core in the dev vendor bundle.
19
- // Keeping core out of vendor avoids duplicate side-effect registrations (e.g.,
20
- // com.tns.FragmentClass, com.tns.NativeScriptActivity) across bundle.mjs and vendor.
21
- // Force runtime-sensitive packages onto the vendor path so they do not drift
22
- // between startup bundle, HTTP-wrapped CommonJS, and base-require semantics
23
- // during HMR sessions.
24
- const ALWAYS_INCLUDE = new Set(['stacktrace-js']);
25
- const ALWAYS_EXCLUDE = new Set([
26
- '@nativescript/android',
27
- '@nativescript/ios',
28
- '@nativescript/types',
29
- '@nativescript/webpack',
30
- // Angular browser animations are not used in NativeScript; excluding reduces
31
- // memory pressure and avoids bringing partial declarations into vendor.
32
- '@angular/animations',
33
- '@angular/platform-browser/animations',
34
- // Not needed at runtime with linked partials; reduce vendor size/memory.
35
- '@angular/platform-browser-dynamic',
36
- // Native add-on helpers pulled by ws or others; exclude in NS dev vendor
37
- 'bufferutil',
38
- 'utf-8-validate',
39
- 'node-gyp-build',
40
- 'bufferutil',
41
- 'utf-8-validate',
42
- 'node-gyp-build',
43
- // All @babel/* and babel-* packages are build-time tools, never runtime deps.
44
- // They get pulled in as peer deps of packages like @nativescript-community/solid-js
45
- // but should never be in the vendor bundle (they require 'fs', 'path', etc.).
46
- '@babel/core',
47
- '@babel/helper-plugin-utils',
48
- '@babel/generator',
49
- '@babel/helper-string-parser',
50
- '@babel/helper-validator-identifier',
51
- '@babel/parser',
52
- '@babel/plugin-syntax-typescript',
53
- '@babel/plugin-transform-typescript',
54
- '@babel/preset-typescript',
55
- '@babel/preset-env',
56
- '@babel/types',
57
- 'babel-preset-solid',
58
- 'babel-plugin-jsx-dom-expressions',
59
- // Heavy dependency not needed in vendor dev bundle; fetch via HTTP loader instead
60
- 'rxjs',
61
- 'nativescript',
62
- 'typescript',
63
- 'ts-node',
64
- 'vue-tsc',
65
- 'ws',
66
- '@types/node',
67
- 'nativescript-theme-core',
68
- // Build-time tools that get pulled in as transitive dependencies but should
69
- // never be in the device vendor bundle (they require Node built-ins like fs,
70
- // path, child_process, etc.). Now that we collect transitive runtime deps,
71
- // these need explicit exclusion.
72
- 'esbuild',
73
- 'prettier',
74
- 'acorn',
75
- 'recast',
76
- 'source-map',
77
- 'source-map-js',
78
- 'tsx',
79
- 'diff',
80
- 'esprima',
81
- // TanStack build-time router tooling (code generation, file-based routing)
82
- '@tanstack/router-plugin',
83
- '@tanstack/router-generator',
84
- '@tanstack/router-utils',
85
- '@tanstack/virtual-file-routes',
86
- // File system / glob utilities — build-time only, require Node fs
87
- 'fdir',
88
- 'picomatch',
89
- 'tinyglobby',
90
- // SSR-only library (bot detection) — not needed on device
91
- 'isbot',
92
- // Type-only packages with no runtime JavaScript
93
- 'csstype',
94
- // NativeScript CLI hook system — build-time only, requires Node os/path
95
- '@nativescript/hook',
96
- // Test runner uses webpack's require.context API which doesn't exist in Vite.
97
- // Including it in the vendor bundle causes __require.context crashes at runtime.
98
- '@nativescript/unit-test-runner',
99
- 'nativescript-unit-test-runner',
100
- // CSS build tools — postcss, tailwindcss, and related tooling are exclusively
101
- // build-time processors. They require Node APIs (process, fs, path) and must
102
- // never run on device. esbuild bundles their transitive deps (picocolors,
103
- // nanoid, etc.) which reference `process` and crash at runtime.
104
- 'tailwindcss',
105
- '@nativescript/tailwind',
106
- 'postcss',
107
- 'autoprefixer',
108
- 'postcss-import',
109
- 'postcss-url',
110
- 'postcss-nested',
111
- 'picocolors',
112
- 'nanoid',
113
- // Server-side SDKs that require Node networking APIs (net, tls, dns, crypto).
114
- // These are backend tools, not device-side.
115
- 'mongodb',
116
- ]);
117
18
  const INDEX_ALIAS_SUFFIXES = ['/index', '/index.js', '/index.android.js', '/index.ios.js', '/index.visionos.js'];
118
19
  export function vendorManifestPlugin(options) {
119
20
  let cachedResult = null;
@@ -268,7 +169,62 @@ async function generateVendorBundle(options) {
268
169
  const { projectRoot, platform, mode, flavor } = options;
269
170
  const collected = collectVendorModules(projectRoot, platform, flavor);
270
171
  const entryCode = createVendorEntry(collected.entries);
172
+ // Externalize @nativescript/core and its subpaths in the vendor bundle so
173
+ // vendored packages (e.g. @nativescript-community/ui-material-bottomsheet)
174
+ // do NOT bring their own copy of core with them. The iOS import map maps
175
+ // `@nativescript/core` → `/ns/core` (the core bridge) at runtime, and the
176
+ // bridge delegates to the canonical Application/View/etc. already set up
177
+ // by bundle.mjs via installCoreAliasesEarly + the globalThis.Application
178
+ // seed. Without this externalization, vendor.mjs bundles a second copy of
179
+ // iOSApplication/View/LayoutBase — the second iosApp never receives the
180
+ // iOS launch event (bundle.mjs's iosApp registered first as
181
+ // UIApplication.delegate), so Application.getRootView() on it returns
182
+ // undefined, and any vendor-internal code that reads .getRootView() or
183
+ // checks `instanceof View` against bundle's classes fails under HMR.
184
+ const nsCoreExternalPlugin = {
185
+ name: 'ns-core-external',
186
+ setup(build) {
187
+ build.onResolve({ filter: /^@nativescript\/core(?:\/.*)?$/ }, (args) => ({
188
+ path: args.path,
189
+ external: true,
190
+ }));
191
+ },
192
+ };
193
+ // Externalize the `solid-js` root specifier for the Solid flavor so
194
+ // vendor-bundled packages (e.g. `@nativescript-community/solid-js`,
195
+ // `solid-navigation`, transitively `solid-js/universal` and
196
+ // `solid-js/store`) don't bake their own copy of solid-js into
197
+ // vendor.mjs. The dev server's import map (see `import-map.ts`)
198
+ // redirects bare `solid-js` to the same `/ns/m/node_modules/solid-js/...`
199
+ // URL that Vite's alias produces for user code and `@solid-refresh`,
200
+ // so V8 dedupes the three import paths down to a single module
201
+ // instance — one `Owner` module-local, one reactive graph, one
202
+ // `$DEVCOMP`/`$PROXY` symbol identity across the whole app.
203
+ //
204
+ // Important: scope this to the EXACT bare `solid-js` specifier. Subpaths
205
+ // like `solid-js/store`, `solid-js/universal`, `solid-js/web` stay
206
+ // bundleable so vendor packages that import them keep working out of
207
+ // the box; those subpaths still go through the unified solid-js
208
+ // runtime via their own `import 'solid-js'` statements (which we just
209
+ // externalized).
210
+ const nsSolidJsExternalPlugin = {
211
+ name: 'ns-solid-js-external',
212
+ setup(build) {
213
+ build.onResolve({ filter: /^solid-js$/ }, (args) => ({
214
+ path: args.path,
215
+ external: true,
216
+ }));
217
+ },
218
+ };
271
219
  const plugins = [
220
+ // Mark @nativescript/core external BEFORE other plugins so esbuild never
221
+ // tries to read/transform core's source files. See comment above.
222
+ nsCoreExternalPlugin,
223
+ // For the Solid flavor, externalize `solid-js` so vendor.mjs and the
224
+ // HTTP-served `@solid-refresh` / user code converge on one runtime
225
+ // realm. See `nsSolidJsExternalPlugin`'s definition for the full
226
+ // duplicate-instance rationale.
227
+ ...(flavor === 'solid' ? [nsSolidJsExternalPlugin] : []),
272
228
  // Apply NativeClass transformer to convert @NativeClass decorated classes to ES5 IIFE pattern.
273
229
  // This MUST run before other plugins to ensure proper transformation.
274
230
  createNativeClassEsbuildPlugin(platform),
@@ -329,9 +285,31 @@ async function generateVendorBundle(options) {
329
285
  '.css': 'text',
330
286
  '.json': 'json',
331
287
  },
332
- define: {
333
- 'process.env.NODE_ENV': JSON.stringify(mode),
334
- },
288
+ // Mirror Vite's main-bundle DefinePlugin in the vendor esbuild build.
289
+ //
290
+ // esbuild's `define` requires every value to be a JS expression
291
+ // expressed as a string (the same constraint Vite normalises away).
292
+ // `getGlobalDefines()` returns a few raw `boolean` values for
293
+ // historical reasons (e.g. `__COMMONJS__: false`,
294
+ // `__UI_USE_XML_PARSER__: true`), so coerce any non-string entries
295
+ // through `JSON.stringify` before handing the table to esbuild.
296
+ define: (() => {
297
+ const raw = getGlobalDefines({
298
+ platform,
299
+ targetMode: mode,
300
+ verbose: !!options.verbose,
301
+ flavor: flavor ?? '',
302
+ isCI: !!process.env.CI,
303
+ });
304
+ const out = {};
305
+ for (const [key, value] of Object.entries(raw)) {
306
+ out[key] = typeof value === 'string' ? value : JSON.stringify(value);
307
+ }
308
+ // Belt-and-suspenders: keep the original NODE_ENV define explicit so
309
+ // future changes to `getGlobalDefines()` can't silently drop it.
310
+ out['process.env.NODE_ENV'] = JSON.stringify(mode);
311
+ return out;
312
+ })(),
335
313
  plugins,
336
314
  // Externalize ALL Node built-in modules. The vendor bundle runs on the
337
315
  // NativeScript device runtime, not Node, so any Node API reference must
@@ -453,232 +431,32 @@ async function generateVendorBundle(options) {
453
431
  entries: collected.entries,
454
432
  };
455
433
  }
456
- function collectVendorModules(projectRoot, platform, flavor) {
457
- const packageJsonPath = path.resolve(projectRoot, 'package.json');
458
- const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
459
- const projectRequire = createRequire(packageJsonPath);
460
- const vendor = new Set();
461
- const visited = new Set();
462
- const queue = [];
463
- const isPackageRootSpecifier = (name) => {
464
- if (!name)
465
- return false;
466
- if (name.startsWith('@')) {
467
- // Scoped: @scope/name is root; anything deeper is subpath
468
- const parts = name.split('/');
469
- return parts.length === 2;
470
- }
471
- // Unscoped: no slash means root; any slash means subpath
472
- return !name.includes('/');
473
- };
474
- const isAngularFlavor = flavor === 'angular';
475
- const addCandidate = (name) => {
476
- if (!name || shouldSkipDependency(name)) {
477
- return;
478
- }
479
- // Avoid pulling Angular compiler/runtime into the dev vendor bundle when
480
- // the current project flavor is not Angular (for example, solid). This
481
- // prevents esbuild from trying to bundle @angular/compiler and its Babel
482
- // toolchain, which requires Node built-ins like fs/path/url.
483
- if (!isAngularFlavor && (name === '@angular/compiler' || name.startsWith('@angular/'))) {
484
- return;
485
- }
486
- // Skip already-visited packages to avoid redundant queue processing
487
- if (visited.has(name)) {
488
- return;
489
- }
490
- visited.add(name);
491
- vendor.add(name);
492
- const isRoot = isPackageRootSpecifier(name);
493
- // Only traverse deps for package roots; subpaths should not attempt package.json resolution
494
- if (isRoot) {
495
- queue.push(name);
496
- }
497
- };
498
- const addDeps = (deps) => {
499
- if (!deps) {
500
- return;
501
- }
502
- for (const name of Object.keys(deps)) {
503
- addCandidate(name);
504
- }
505
- };
506
- addDeps(pkg.dependencies);
507
- addDeps(pkg.optionalDependencies);
508
- for (const name of ALWAYS_INCLUDE) {
509
- // Some force-included packages are only present transitively in apps that
510
- // actually use them. Skip missing packages quietly so unrelated projects do
511
- // not fail vendor collection just because the policy list names them.
512
- if (canResolveDependencyPackageJson(name, projectRequire)) {
513
- addCandidate(name);
514
- }
515
- }
516
- // Ensure Android Activity proxy is present for SBG scanning in dev/HMR
517
- // and non-HMR builds alike: explicitly include the side-effect module
518
- // that registers `com.tns.NativeScriptActivity`.
519
- if (platform === 'android') {
520
- addCandidate('@nativescript/core/ui/frame/activity.android');
521
- }
522
- if (pkg.dependencies?.['nativescript-vue'] && pkg.devDependencies?.vue) {
523
- addCandidate('vue');
524
- }
525
- if (pkg.dependencies?.['@nativescript/angular']) {
526
- if (pkg.dependencies?.['@angular/core']) {
527
- addCandidate('@angular/core');
528
- }
529
- if (pkg.dependencies?.['@angular/common']) {
530
- addCandidate('@angular/common');
531
- }
532
- // RxJS is large and not required inside the vendor bundle for dev HMR.
533
- // Avoid bundling to reduce memory pressure; let app import via HTTP loader.
534
- }
535
- if (pkg.dependencies?.['react-nativescript']) {
536
- if (pkg.dependencies?.react) {
537
- addCandidate('react');
538
- }
539
- if (pkg.dependencies?.['react-dom']) {
540
- addCandidate('react-dom');
541
- }
542
- }
543
- // SolidJS / TanStack Router: when @nativescript/tanstack-router is a dependency,
544
- // its runtime deps (@tanstack/solid-router, @tanstack/router-core, @tanstack/history)
545
- // MUST be in the vendor bundle. These packages:
546
- // 1. Use browser APIs (window.dispatchEvent) that don't exist in NativeScript — they
547
- // must be bundled where the NativeScript wrapper intercepts those calls
548
- // 2. Contain JSX source that needs Solid compilation (dist/source/*.jsx) — the HTTP
549
- // fallback can't compile node_modules JSX since vite-plugin-solid skips it
550
- // 3. Import solid-js internally — loading via HTTP creates a separate solid-js instance
551
- // esbuild uses the 'import' condition (not 'solid'), resolving to pre-compiled
552
- // dist/esm/*.js which avoids all three issues.
553
- if (pkg.dependencies?.['@nativescript/tanstack-router']) {
554
- addCandidate('@tanstack/solid-router');
555
- addCandidate('@tanstack/router-core');
556
- addCandidate('@tanstack/history');
557
- }
558
- parseEnvList(process.env.NS_VENDOR_INCLUDE).forEach(addCandidate);
559
- const projectDeps = {
560
- dependencies: new Set(Object.keys(pkg.dependencies ?? {})),
561
- optional: new Set(Object.keys(pkg.optionalDependencies ?? {})),
562
- dev: new Set(Object.keys(pkg.devDependencies ?? {})),
563
- };
564
- while (queue.length) {
565
- const specifier = queue.shift();
566
- const dependencyPkg = readDependencyPackageJson(specifier, projectRequire);
567
- if (!dependencyPkg) {
568
- continue;
569
- }
570
- const peerDependencies = Object.keys(dependencyPkg.peerDependencies ?? {});
571
- for (const peer of peerDependencies) {
572
- if (shouldSkipDependency(peer)) {
573
- continue;
574
- }
575
- if (projectDeps.dependencies.has(peer) || projectDeps.optional.has(peer) || projectDeps.dev.has(peer)) {
576
- addCandidate(peer);
577
- }
578
- }
579
- // NOTE: We intentionally do NOT collect transitive runtime dependencies
580
- // here. The import map + runtime specifier normalization handles non-vendor
581
- // packages by routing them through HTTP to the Vite dev server. This avoids
582
- // the fragility of trying to esbuild-bundle every transitive dep (which can
583
- // fail due to Node built-ins, type-only packages, duplicate module instances,
584
- // etc.). Only direct project dependencies go into the vendor bundle.
585
- }
586
- parseEnvList(process.env.NS_VENDOR_EXCLUDE).forEach((name) => {
587
- vendor.delete(name);
588
- });
589
- return {
590
- entries: Array.from(vendor).sort(),
591
- };
592
- }
593
- function shouldSkipDependency(name) {
594
- if (!name) {
595
- return true;
596
- }
597
- if (ALWAYS_EXCLUDE.has(name)) {
598
- return true;
599
- }
600
- // All Babel packages are build tools — never bundle into device runtime.
601
- // They require Node built-ins (fs, path, url) that don't exist on device.
602
- if (name.startsWith('@babel/') || name.startsWith('babel-')) {
603
- return true;
604
- }
605
- // Dev tools and type-only packages — not needed on device
606
- if (name.startsWith('@solid-devtools/')) {
607
- return true;
608
- }
609
- if (name.startsWith('@types/')) {
610
- return true;
611
- }
612
- // PostCSS ecosystem — all build-time CSS processing
613
- if (name === 'postcss' || name.startsWith('postcss-')) {
614
- return true;
615
- }
616
- // Tailwind ecosystem — build-time only CSS framework
617
- if (name.includes('tailwind')) {
618
- return true;
619
- }
620
- // Test runners and frameworks — never needed on device
621
- if (name.includes('test-runner') || name.includes('unit-test')) {
622
- return true;
623
- }
624
- // Linters and formatters — build-time tools
625
- if (name.includes('eslint') || name.includes('stylelint')) {
626
- return true;
627
- }
628
- if (name.startsWith('.')) {
629
- return true;
630
- }
631
- if (name.startsWith('file:')) {
632
- return true;
633
- }
634
- if (name.startsWith('workspace:')) {
635
- return true;
636
- }
637
- if (name.startsWith('link:')) {
638
- return true;
639
- }
640
- return false;
641
- }
642
- export const __test_collectVendorModules = collectVendorModules;
643
434
  export const __test_createVendorBundleRuntimeModule = createVendorBundleRuntimeModule;
644
- function canResolveDependencyPackageJson(specifier, projectRequire) {
645
- try {
646
- projectRequire.resolve(`${specifier}/package.json`);
647
- return true;
648
- }
649
- catch {
650
- return false;
651
- }
652
- }
653
- function readDependencyPackageJson(specifier, projectRequire) {
654
- try {
655
- const packageJsonPath = projectRequire.resolve(`${specifier}/package.json`);
656
- return JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
657
- }
658
- catch (error) {
659
- if (process.env.VITE_DEBUG_LOGS) {
660
- console.warn(`[vendor] unable to resolve ${specifier} package.json`, error);
661
- }
662
- return null;
663
- }
664
- }
665
- function parseEnvList(value) {
666
- if (!value) {
667
- return [];
668
- }
669
- return value
670
- .split(',')
671
- .map((token) => token.trim())
672
- .filter(Boolean);
673
- }
435
+ export { collectVendorModules as __test_collectVendorModules, isUnvendorableLocalSource as __test_isUnvendorableLocalSource, packageHasCompiledJsEntry as __test_packageHasCompiledJsEntry } from './manifest-collect.js';
674
436
  function createVendorEntry(entries) {
675
437
  if (!entries.length) {
676
438
  return `export const __nsVendorModuleMap = {};
677
439
  `;
678
440
  }
679
- const imports = entries.map((specifier, index) => `import * as __nsVendor_${index} from ${JSON.stringify(specifier)};`).join('\n');
441
+ // Emit a side-effect-only import FIRST for each entry, then the namespace
442
+ // import we actually expose through `__nsVendorModuleMap`. Per the ESM
443
+ // spec, `import "pkg";` (no clause) guarantees module body evaluation, and
444
+ // esbuild treats these as DCE-immune even when the package declares
445
+ // `"sideEffects": false`. Without this, packages whose top-level
446
+ // statements install runtime patches (e.g. `@nativescript-community/text`
447
+ // monkey-patching `TextBase.prototype.setTextDecorationAndTransform` via
448
+ // `overrideSpanAndFormattedString()` invoked from
449
+ // `@nativescript-community/ui-label/index-common.js` line 12) can have
450
+ // their bodies elided by esbuild — exports stay resolvable via the
451
+ // namespace, but the runtime patches never fire, producing line-height /
452
+ // letter-spacing / formatted-text rendering divergence between HMR
453
+ // (vendor.mjs via HTTP) and no-HMR (single Rolldown bundle that inlines
454
+ // everything anyway). This affects any NS plugin that relies on top-level
455
+ // side-effects to wire up renderer behavior.
456
+ const sideEffectImports = entries.map((specifier) => `import ${JSON.stringify(specifier)};`).join('\n');
457
+ const namespaceImports = entries.map((specifier, index) => `import * as __nsVendor_${index} from ${JSON.stringify(specifier)};`).join('\n');
680
458
  const modules = entries.map((specifier, index) => `${JSON.stringify(specifier)}: __nsVendor_${index}`).join(',\n ');
681
- return `${imports}\n\nexport const __nsVendorModuleMap = {\n ${modules}\n};\n`;
459
+ return `${sideEffectImports}\n\n${namespaceImports}\n\nexport const __nsVendorModuleMap = {\n ${modules}\n};\n`;
682
460
  }
683
461
  function createVendorBundleRuntimeModule(result) {
684
462
  return `${result.code}
@@ -743,421 +521,6 @@ function createSbgVendorAssetCode(platform) {
743
521
  lines.push('export const __nsVendorModuleMap = {};\nexport default {};\n');
744
522
  return lines.join('\n');
745
523
  }
746
- function createVendorEsbuildPlugin(projectRoot) {
747
- return {
748
- name: 'ns-vendor-resolver',
749
- setup(build) {
750
- const debug = process.env.VITE_DEBUG_LOGS === 'true' || process.env.VITE_DEBUG_LOGS === '1';
751
- build.onResolve({ filter: /^~\/package\.json$/ }, () => ({
752
- path: path.resolve(projectRoot, 'package.json'),
753
- }));
754
- build.onResolve({ filter: /^module$/ }, () => ({
755
- path: 'ns-vendor-module-shim',
756
- namespace: 'ns-vendor',
757
- }));
758
- build.onLoad({ filter: /^ns-vendor-module-shim$/, namespace: 'ns-vendor' }, () => ({
759
- contents: vendorModuleShim,
760
- loader: 'js',
761
- }));
762
- // Stub Angular animations in vendor to avoid bundling browser-only code.
763
- // Provide named exports expected by @nativescript/angular to satisfy esbuild.
764
- const PB_ANIMATIONS_ID = 'ns-animations-pb-shim';
765
- const ANIMATIONS_BROWSER_ID = 'ns-animations-browser-shim';
766
- const ANIMATIONS_ID = 'ns-animations-noop';
767
- // @angular/platform-browser/animations -> provide concrete named stubs
768
- build.onResolve({ filter: /^@angular\/platform-browser\/animations(?:\/.*)?$/ }, (args) => {
769
- if (debug) {
770
- try {
771
- console.log('[vendor] map', args.path, '->', PB_ANIMATIONS_ID);
772
- }
773
- catch { }
774
- }
775
- return { path: PB_ANIMATIONS_ID, namespace: 'ns-vendor' };
776
- });
777
- build.onLoad({ filter: new RegExp(`^${PB_ANIMATIONS_ID}$`), namespace: 'ns-vendor' }, () => ({
778
- contents: [
779
- 'export default {};',
780
- // Commonly imported symbols by @nativescript/angular
781
- 'export class AnimationBuilder {};',
782
- 'export const \u0275BrowserAnimationBuilder = class {};',
783
- 'export const \u0275AnimationEngine = class {};',
784
- 'export const \u0275AnimationRendererFactory = class {};',
785
- 'export const \u0275WebAnimationsStyleNormalizer = class {};',
786
- // Typical platform-browser/animations APIs exported; safe no-ops
787
- 'export class BrowserAnimationsModule {};',
788
- 'export class NoopAnimationsModule {};',
789
- 'export const provideAnimations = (..._args) => [];',
790
- 'export const provideNoopAnimations = (..._args) => [];',
791
- // Marker used by some Angular internals
792
- 'export const ANIMATION_MODULE_TYPE = void 0;',
793
- ].join('\n'),
794
- loader: 'js',
795
- }));
796
- // @angular/animations/browser -> provide ɵ* engine/renderer/style normalizer stubs
797
- build.onResolve({ filter: /^@angular\/animations\/browser(?:\/.*)?$/ }, (args) => {
798
- if (debug) {
799
- try {
800
- console.log('[vendor] map', args.path, '->', ANIMATIONS_BROWSER_ID);
801
- }
802
- catch { }
803
- }
804
- return { path: ANIMATIONS_BROWSER_ID, namespace: 'ns-vendor' };
805
- });
806
- build.onLoad({ filter: new RegExp(`^${ANIMATIONS_BROWSER_ID}$`), namespace: 'ns-vendor' }, () => ({
807
- contents: [
808
- 'export default {};',
809
- 'export class AnimationDriver {};',
810
- 'export const \u0275AnimationRendererFactory = class {};',
811
- 'export const \u0275AnimationStyleNormalizer = class {};',
812
- 'export const \u0275WebAnimationsStyleNormalizer = class {};',
813
- 'export const \u0275AnimationEngine = class {};',
814
- // Convenience alias if any consumers import non-ɵ name
815
- 'export const AnimationStyleNormalizer = \u0275AnimationStyleNormalizer;',
816
- ].join('\n'),
817
- loader: 'js',
818
- }));
819
- // @angular/animations -> broad no-op surface
820
- build.onResolve(
821
- // Keep generic mapping for @angular/animations base; /browser is handled above
822
- { filter: /^@angular\/animations(?:$|\/)$/ }, (args) => {
823
- if (debug) {
824
- try {
825
- console.log('[vendor] map', args.path, '->', ANIMATIONS_ID);
826
- }
827
- catch { }
828
- }
829
- return { path: ANIMATIONS_ID, namespace: 'ns-vendor' };
830
- });
831
- build.onLoad({ filter: new RegExp(`^${ANIMATIONS_ID}$`), namespace: 'ns-vendor' }, () => ({
832
- contents: [
833
- 'export default {};',
834
- // Provide names sometimes (incorrectly) imported from @angular/animations by wrappers
835
- 'export class AnimationBuilder {};',
836
- 'export const \u0275BrowserAnimationBuilder = class {};',
837
- 'export const \u0275AnimationEngine = class {};',
838
- 'export const \u0275AnimationRendererFactory = class {};',
839
- 'export const \u0275WebAnimationsStyleNormalizer = class {};',
840
- 'export const ANIMATION_MODULE_TYPE = void 0;',
841
- // Export a few common tokens as harmless stubs
842
- 'export const animate = (..._a) => ({});',
843
- 'export const state = (..._a) => ({});',
844
- 'export const style = (..._a) => ({});',
845
- 'export const transition = (..._a) => ({});',
846
- 'export const trigger = (..._a) => ({});',
847
- 'export const sequence = (..._a) => ({});',
848
- 'export const group = (..._a) => ({});',
849
- 'export const query = (..._a) => ({});',
850
- 'export const stagger = (..._a) => ({});',
851
- 'export const keyframes = (..._a) => ({});',
852
- ].join('\n'),
853
- loader: 'js',
854
- }));
855
- },
856
- };
857
- }
858
- /**
859
- * esbuild plugin to compile .jsx/.tsx files from Solid packages through
860
- * babel-preset-solid. Without this, esbuild uses its default React JSX
861
- * transform, producing React.createElement calls that crash at runtime.
862
- *
863
- * Only applied to files inside node_modules that have .jsx or .tsx extension.
864
- */
865
- function createSolidJsxEsbuildPlugin(projectRoot) {
866
- // Lazy-load Babel and the Solid preset so they're only required when
867
- // the Solid flavor is active.
868
- let babel;
869
- let solidPreset;
870
- return {
871
- name: 'ns-vendor-solid-jsx',
872
- setup(build) {
873
- // Intercept .jsx and .tsx files from node_modules
874
- build.onLoad({ filter: /node_modules\/.*\.[jt]sx$/ }, async (args) => {
875
- try {
876
- if (!babel) {
877
- babel = await import('@babel/core');
878
- // babel-preset-solid is the standard Solid JSX transform
879
- solidPreset = (await import('babel-preset-solid')).default;
880
- }
881
- const source = await readFile(args.path, 'utf-8');
882
- const result = await babel.transformAsync(source, {
883
- filename: args.path,
884
- presets: [
885
- [
886
- solidPreset,
887
- {
888
- generate: 'universal',
889
- hydratable: false,
890
- moduleName: '@nativescript-community/solid-js',
891
- },
892
- ],
893
- ],
894
- parserOpts: {
895
- plugins: ['jsx', ...(args.path.endsWith('.tsx') ? ['typescript'] : [])],
896
- },
897
- ast: false,
898
- sourceMaps: false,
899
- configFile: false,
900
- babelrc: false,
901
- });
902
- if (result?.code) {
903
- return { contents: result.code, loader: 'js' };
904
- }
905
- }
906
- catch (e) {
907
- console.warn(`[ns-vendor-solid-jsx] failed to transform ${args.path}:`, e?.message || e);
908
- }
909
- // Fall through to esbuild's default handling
910
- return undefined;
911
- });
912
- },
913
- };
914
- }
915
- /**
916
- * Minimal esbuild plugin to run Angular linker (Babel) over partial-compiled
917
- * Angular packages in node_modules. This converts ɵɵngDeclare* calls into
918
- * ɵɵdefine* so runtime doesn't require the JIT compiler.
919
- */
920
- function angularLinkerEsbuildPlugin(projectRoot) {
921
- // Lazily resolve Babel and Angular linker from the project to avoid hard deps
922
- let babel = null;
923
- let createLinker = null;
924
- let angularFileSystem = null;
925
- async function ensureDeps() {
926
- if (babel && createLinker)
927
- return;
928
- try {
929
- const req = createRequire(projectRoot + '/package.json');
930
- // Resolve from the application project first
931
- const babelPath = req.resolve('@babel/core');
932
- const linkerPath = req.resolve('@angular/compiler-cli/linker/babel');
933
- babel = (await import(babelPath));
934
- const linkerMod = await import(linkerPath);
935
- createLinker = linkerMod.createLinkerPlugin || linkerMod.createEs2015LinkerPlugin || null;
936
- }
937
- catch {
938
- // As a fallback, try local resolution (hoisted installs)
939
- try {
940
- babel = (await import('@babel/core'));
941
- }
942
- catch { }
943
- try {
944
- const linkerMod = await import('@angular/compiler-cli/linker/babel');
945
- createLinker = linkerMod.createLinkerPlugin || linkerMod.createEs2015LinkerPlugin || null;
946
- }
947
- catch { }
948
- }
949
- // Angular 21+ requires a fileSystem for the linker plugin
950
- if (!angularFileSystem) {
951
- try {
952
- const req = createRequire(projectRoot + '/package.json');
953
- const cliPath = req.resolve('@angular/compiler-cli');
954
- const cliMod = await import(cliPath);
955
- if (cliMod.NodeJSFileSystem) {
956
- angularFileSystem = new cliMod.NodeJSFileSystem();
957
- }
958
- }
959
- catch { }
960
- if (!angularFileSystem) {
961
- try {
962
- const cliMod = await import('@angular/compiler-cli');
963
- if (cliMod.NodeJSFileSystem) {
964
- angularFileSystem = new cliMod.NodeJSFileSystem();
965
- }
966
- }
967
- catch { }
968
- }
969
- if (!angularFileSystem) {
970
- // Minimal fallback
971
- const nodePath = await import('node:path');
972
- const nodeFs = await import('node:fs');
973
- angularFileSystem = {
974
- resolve: (...paths) => nodePath.resolve(...paths),
975
- dirname: (p) => nodePath.dirname(p),
976
- join: (...paths) => nodePath.join(...paths),
977
- isRooted: (p) => nodePath.isAbsolute(p),
978
- exists: (p) => nodeFs.existsSync(p),
979
- readFile: (p) => nodeFs.readFileSync(p, 'utf8'),
980
- };
981
- }
982
- }
983
- }
984
- // Restrict to Angular framework packages to minimize esbuild memory usage.
985
- const FILTER = /node_modules\/(?:@angular|@nativescript\/angular)\/.*\.[mc]?js$/;
986
- return {
987
- name: 'ns-angular-linker',
988
- async setup(build) {
989
- const debug = process.env.VITE_DEBUG_LOGS === 'true' || process.env.VITE_DEBUG_LOGS === '1';
990
- await ensureDeps();
991
- if (!babel || !createLinker) {
992
- // Nothing to do if deps unavailable
993
- return;
994
- }
995
- build.onLoad({ filter: FILTER }, async (args) => {
996
- try {
997
- const source = await readFile(args.path, 'utf8');
998
- // Fast-path: only run linker when partial declarations are present
999
- if (!(source.includes('\u0275\u0275ngDeclare') || source.includes('ɵɵngDeclare'))) {
1000
- return { contents: source, loader: 'js' };
1001
- }
1002
- const plugin = createLinker({
1003
- sourceMapping: false,
1004
- fileSystem: angularFileSystem,
1005
- });
1006
- if (debug) {
1007
- try {
1008
- console.log('[ns-angular-linker][vendor] linking', args.path);
1009
- }
1010
- catch { }
1011
- }
1012
- const result = await babel.transformAsync(source, {
1013
- filename: args.path,
1014
- configFile: false,
1015
- babelrc: false,
1016
- sourceMaps: false,
1017
- compact: false,
1018
- plugins: [plugin],
1019
- });
1020
- return {
1021
- contents: (result && result.code) || source,
1022
- loader: 'js',
1023
- };
1024
- }
1025
- catch (e) {
1026
- // On any failure, return original source to avoid breaking the build
1027
- return { contents: await readFile(args.path, 'utf8'), loader: 'js' };
1028
- }
1029
- });
1030
- },
1031
- };
1032
- }
1033
- const vendorModuleShim = `
1034
- const g = globalThis;
1035
- const BACKSLASH = String.fromCharCode(92);
1036
-
1037
- function toForwardSlashes(input) {
1038
- return String(input ?? '').split(BACKSLASH).join('/');
1039
- }
1040
-
1041
- function getNativeScriptRequire() {
1042
- const nsRequire = typeof g.require === "function" ? g.require : null;
1043
- if (nsRequire) {
1044
- return nsRequire;
1045
- }
1046
- const legacy = g.__nsRequire;
1047
- if (typeof legacy === "function") {
1048
- return legacy;
1049
- }
1050
- return null;
1051
- }
1052
-
1053
- function getDocumentsPath() {
1054
- const cached = g.__NS_DOCUMENTS_PATH__;
1055
- if (typeof cached === "string" && cached.length) {
1056
- return toForwardSlashes(cached);
1057
- }
1058
- try {
1059
- const core = g.require ? g.require("@nativescript/core") : null;
1060
- const docsFolder = core?.knownFolders?.documents?.();
1061
- const docPath = docsFolder?.path;
1062
- if (docPath) {
1063
- const normalized = toForwardSlashes(docPath);
1064
- g.__NS_DOCUMENTS_PATH__ = normalized;
1065
- return normalized;
1066
- }
1067
- } catch (_err) {
1068
- // ignore - fallback to raw specifier
1069
- }
1070
- return null;
1071
- }
1072
-
1073
- function collapseSegments(input) {
1074
- const segments = [];
1075
- const parts = input.split('/');
1076
- for (const part of parts) {
1077
- if (!part || part === ".") {
1078
- continue;
1079
- }
1080
- if (part === "..") {
1081
- if (segments.length && segments[segments.length - 1] !== "..") {
1082
- segments.pop();
1083
- continue;
1084
- }
1085
- }
1086
- segments.push(part);
1087
- }
1088
- const leadingSlash = input.startsWith('/');
1089
- return (leadingSlash ? '/' : '') + segments.join('/');
1090
- }
1091
-
1092
- function normalizeSpecifier(spec) {
1093
- let value = String(spec ?? "");
1094
- value = toForwardSlashes(value);
1095
- const docsPath = getDocumentsPath();
1096
- if (value.startsWith("__NSDOC__/")) {
1097
- if (docsPath) {
1098
- value = docsPath + '/' + value.slice("__NSDOC__/".length);
1099
- } else {
1100
- value = value.slice("__NSDOC__/".length);
1101
- }
1102
- }
1103
- if (value.startsWith("~/") && docsPath) {
1104
- value = docsPath + '/' + value.slice(2);
1105
- }
1106
- if (value.startsWith("file://")) {
1107
- const stripped = value.slice("file://".length);
1108
- value = stripped.startsWith('/') ? stripped : '/' + stripped;
1109
- }
1110
- if (value.includes("/../") || value.includes("/./")) {
1111
- value = collapseSegments(value);
1112
- }
1113
- return value;
1114
- }
1115
-
1116
- export function createRequire(_url) {
1117
- const nsRequire = getNativeScriptRequire();
1118
- if (!nsRequire) {
1119
- return function () {
1120
- throw new Error("NativeScript require() is not available in this context");
1121
- };
1122
- }
1123
- const req = function (id) {
1124
- const normalizedId = normalizeSpecifier(id);
1125
- if (
1126
- normalizedId.includes("../data/patch.json") ||
1127
- normalizedId.includes("css-tree/lib/data/patch.json")
1128
- ) {
1129
- return {
1130
- atrules: {},
1131
- properties: {},
1132
- types: {},
1133
- };
1134
- }
1135
- if (normalizedId.includes("mdn-data/")) {
1136
- return {};
1137
- }
1138
- if (
1139
- normalizedId.endsWith("/package.json") ||
1140
- normalizedId.includes("../package.json")
1141
- ) {
1142
- return { version: "0.0.0" };
1143
- }
1144
- if (normalizedId.endsWith(".json")) {
1145
- return {};
1146
- }
1147
- return nsRequire(normalizedId);
1148
- };
1149
- req.resolve = nsRequire.resolve
1150
- ? function (id) {
1151
- return nsRequire.resolve(id);
1152
- }
1153
- : function (id) {
1154
- return id;
1155
- };
1156
- return req;
1157
- }
1158
-
1159
- export default { createRequire };
1160
- `;
1161
524
  function stripIndexSuffix(specifier) {
1162
525
  return specifier.replace(/\/(?:(?:index)(?:\.[^.\/]+)?)$/, '');
1163
526
  }