@nativescript/vite 8.0.0-alpha.1 → 8.0.0-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/configuration/angular.d.ts +1 -1
- package/configuration/angular.js +323 -119
- package/configuration/angular.js.map +1 -1
- package/configuration/base.js +41 -24
- package/configuration/base.js.map +1 -1
- package/configuration/javascript.js +3 -3
- package/configuration/javascript.js.map +1 -1
- package/configuration/solid.js +7 -0
- package/configuration/solid.js.map +1 -1
- package/configuration/typescript.js +3 -3
- package/configuration/typescript.js.map +1 -1
- package/helpers/angular/angular-linker.js +39 -34
- package/helpers/angular/angular-linker.js.map +1 -1
- package/helpers/angular/inline-decorator-component-templates.d.ts +3 -0
- package/helpers/angular/inline-decorator-component-templates.js +400 -0
- package/helpers/angular/inline-decorator-component-templates.js.map +1 -0
- package/helpers/angular/shared-linker.d.ts +7 -0
- package/helpers/angular/shared-linker.js +37 -1
- package/helpers/angular/shared-linker.js.map +1 -1
- package/helpers/angular/synthesize-decorator-ctor-parameters.d.ts +1 -0
- package/helpers/angular/synthesize-decorator-ctor-parameters.js +256 -0
- package/helpers/angular/synthesize-decorator-ctor-parameters.js.map +1 -0
- package/helpers/angular/synthesize-injectable-factories.d.ts +3 -0
- package/helpers/angular/synthesize-injectable-factories.js +414 -0
- package/helpers/angular/synthesize-injectable-factories.js.map +1 -0
- package/helpers/commonjs-plugins.d.ts +5 -2
- package/helpers/commonjs-plugins.js +126 -0
- package/helpers/commonjs-plugins.js.map +1 -1
- package/helpers/esbuild-platform-resolver.js +5 -5
- package/helpers/esbuild-platform-resolver.js.map +1 -1
- package/helpers/external-configs.d.ts +9 -1
- package/helpers/external-configs.js +31 -6
- package/helpers/external-configs.js.map +1 -1
- package/helpers/import-meta-path.d.ts +4 -0
- package/helpers/import-meta-path.js +5 -0
- package/helpers/import-meta-path.js.map +1 -0
- package/helpers/import-specifier.d.ts +1 -0
- package/helpers/import-specifier.js +18 -0
- package/helpers/import-specifier.js.map +1 -0
- package/helpers/main-entry.d.ts +5 -2
- package/helpers/main-entry.js +112 -95
- package/helpers/main-entry.js.map +1 -1
- package/helpers/nativeclass-transform.js +8 -127
- package/helpers/nativeclass-transform.js.map +1 -1
- package/helpers/nativeclass-transformer-plugin.d.ts +12 -1
- package/helpers/nativeclass-transformer-plugin.js +175 -36
- package/helpers/nativeclass-transformer-plugin.js.map +1 -1
- package/hmr/client/css-handler.js +60 -20
- package/hmr/client/css-handler.js.map +1 -1
- package/hmr/client/index.js +524 -23
- package/hmr/client/index.js.map +1 -1
- package/hmr/client/utils.js +57 -6
- package/hmr/client/utils.js.map +1 -1
- package/hmr/entry-runtime.d.ts +10 -0
- package/hmr/entry-runtime.js +263 -21
- package/hmr/entry-runtime.js.map +1 -1
- package/hmr/frameworks/angular/client/index.d.ts +2 -1
- package/hmr/frameworks/angular/client/index.js +72 -19
- package/hmr/frameworks/angular/client/index.js.map +1 -1
- package/hmr/frameworks/angular/server/linker.js +36 -2
- package/hmr/frameworks/angular/server/linker.js.map +1 -1
- package/hmr/frameworks/angular/server/strategy.js +20 -5
- package/hmr/frameworks/angular/server/strategy.js.map +1 -1
- package/hmr/frameworks/typescript/server/strategy.js +8 -2
- package/hmr/frameworks/typescript/server/strategy.js.map +1 -1
- package/hmr/helpers/ast-normalizer.js +22 -10
- package/hmr/helpers/ast-normalizer.js.map +1 -1
- package/hmr/server/constants.d.ts +1 -0
- package/hmr/server/constants.js +2 -0
- package/hmr/server/constants.js.map +1 -1
- package/hmr/server/core-sanitize.d.ts +43 -0
- package/hmr/server/core-sanitize.js +219 -13
- package/hmr/server/core-sanitize.js.map +1 -1
- package/hmr/server/import-map.d.ts +65 -0
- package/hmr/server/import-map.js +219 -0
- package/hmr/server/import-map.js.map +1 -0
- package/hmr/server/index.d.ts +2 -1
- package/hmr/server/index.js.map +1 -1
- package/hmr/server/runtime-graph-filter.d.ts +5 -0
- package/hmr/server/runtime-graph-filter.js +21 -0
- package/hmr/server/runtime-graph-filter.js.map +1 -0
- package/hmr/server/shared-transform-request.d.ts +12 -0
- package/hmr/server/shared-transform-request.js +137 -0
- package/hmr/server/shared-transform-request.js.map +1 -0
- package/hmr/server/vite-plugin.d.ts +21 -1
- package/hmr/server/vite-plugin.js +443 -22
- package/hmr/server/vite-plugin.js.map +1 -1
- package/hmr/server/websocket-angular-entry.d.ts +2 -0
- package/hmr/server/websocket-angular-entry.js +68 -0
- package/hmr/server/websocket-angular-entry.js.map +1 -0
- package/hmr/server/websocket-angular-hot-update.d.ts +61 -0
- package/hmr/server/websocket-angular-hot-update.js +239 -0
- package/hmr/server/websocket-angular-hot-update.js.map +1 -0
- package/hmr/server/websocket-core-bridge.d.ts +23 -0
- package/hmr/server/websocket-core-bridge.js +360 -0
- package/hmr/server/websocket-core-bridge.js.map +1 -0
- package/hmr/server/websocket-graph-upsert.d.ts +6 -0
- package/hmr/server/websocket-graph-upsert.js +13 -0
- package/hmr/server/websocket-graph-upsert.js.map +1 -0
- package/hmr/server/websocket-module-bindings.d.ts +6 -0
- package/hmr/server/websocket-module-bindings.js +471 -0
- package/hmr/server/websocket-module-bindings.js.map +1 -0
- package/hmr/server/websocket-module-specifiers.d.ts +37 -0
- package/hmr/server/websocket-module-specifiers.js +637 -0
- package/hmr/server/websocket-module-specifiers.js.map +1 -0
- package/hmr/server/websocket.d.ts +26 -3
- package/hmr/server/websocket.js +1402 -678
- package/hmr/server/websocket.js.map +1 -1
- package/hmr/shared/package-classifier.d.ts +9 -0
- package/hmr/shared/package-classifier.js +58 -0
- package/hmr/shared/package-classifier.js.map +1 -0
- package/hmr/shared/runtime/browser-runtime-contract.d.ts +64 -0
- package/hmr/shared/runtime/browser-runtime-contract.js +54 -0
- package/hmr/shared/runtime/browser-runtime-contract.js.map +1 -0
- package/hmr/shared/runtime/dev-overlay.d.ts +38 -0
- package/hmr/shared/runtime/dev-overlay.js +675 -0
- package/hmr/shared/runtime/dev-overlay.js.map +1 -0
- package/hmr/shared/runtime/http-only-boot.d.ts +1 -0
- package/hmr/shared/runtime/http-only-boot.js +53 -6
- package/hmr/shared/runtime/http-only-boot.js.map +1 -1
- package/hmr/shared/runtime/module-provenance.d.ts +1 -0
- package/hmr/shared/runtime/module-provenance.js +66 -0
- package/hmr/shared/runtime/module-provenance.js.map +1 -0
- package/hmr/shared/runtime/platform-polyfills.d.ts +26 -0
- package/hmr/shared/runtime/platform-polyfills.js +122 -0
- package/hmr/shared/runtime/platform-polyfills.js.map +1 -0
- package/hmr/shared/runtime/root-placeholder.d.ts +1 -0
- package/hmr/shared/runtime/root-placeholder.js +576 -76
- package/hmr/shared/runtime/root-placeholder.js.map +1 -1
- package/hmr/shared/runtime/session-bootstrap.d.ts +1 -0
- package/hmr/shared/runtime/session-bootstrap.js +146 -0
- package/hmr/shared/runtime/session-bootstrap.js.map +1 -0
- package/hmr/shared/runtime/vendor-bootstrap.js +51 -6
- package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
- package/hmr/shared/vendor/manifest.d.ts +7 -0
- package/hmr/shared/vendor/manifest.js +363 -23
- package/hmr/shared/vendor/manifest.js.map +1 -1
- package/hmr/shared/vendor/registry.js +104 -7
- package/hmr/shared/vendor/registry.js.map +1 -1
- package/package.json +12 -2
- package/runtime/core-aliases-early.js +83 -32
- package/runtime/core-aliases-early.js.map +1 -1
- package/shims/solid-jsx-runtime.d.ts +7 -0
- package/shims/solid-jsx-runtime.js +17 -0
- package/shims/solid-jsx-runtime.js.map +1 -0
package/configuration/angular.js
CHANGED
|
@@ -4,14 +4,40 @@ import fs from 'node:fs';
|
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import angular from '@analogjs/vite-plugin-angular';
|
|
6
6
|
import { angularLinkerVitePlugin, angularLinkerVitePluginPost } from '../helpers/angular/angular-linker.js';
|
|
7
|
-
import {
|
|
7
|
+
import { synthesizeMissingInjectableFactories } from '../helpers/angular/synthesize-injectable-factories.js';
|
|
8
|
+
import { ensureSharedAngularLinker, resolveAngularFileSystem } from '../helpers/angular/shared-linker.js';
|
|
9
|
+
import { inlineDecoratorComponentTemplates } from '../helpers/angular/inline-decorator-component-templates.js';
|
|
10
|
+
import { synthesizeDecoratorCtorParameters } from '../helpers/angular/synthesize-decorator-ctor-parameters.js';
|
|
8
11
|
import { containsRealNgDeclare } from '../helpers/angular/util.js';
|
|
9
12
|
import { baseConfig } from './base.js';
|
|
10
13
|
import { getCliFlags } from '../helpers/cli-flags.js';
|
|
14
|
+
import { resolveRelativeToImportMeta } from '../helpers/import-meta-path.js';
|
|
15
|
+
// Lazily import the Angular linker factory function. Used by chunk-level linkers
|
|
16
|
+
// to create FRESH plugin instances per invocation (avoiding stale state in watch mode).
|
|
17
|
+
let _cachedLinkerFactory = null;
|
|
18
|
+
async function importLinkerFactory() {
|
|
19
|
+
if (_cachedLinkerFactory)
|
|
20
|
+
return _cachedLinkerFactory;
|
|
21
|
+
const req = createRequire(process.cwd() + '/package.json');
|
|
22
|
+
try {
|
|
23
|
+
const linkerPath = req.resolve('@angular/compiler-cli/linker/babel');
|
|
24
|
+
const linkerMod = await import(linkerPath);
|
|
25
|
+
_cachedLinkerFactory = linkerMod.createLinkerPlugin || linkerMod.createEs2015LinkerPlugin || null;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
try {
|
|
29
|
+
const linkerMod = await import('@angular/compiler-cli/linker/babel');
|
|
30
|
+
_cachedLinkerFactory = linkerMod.createLinkerPlugin || linkerMod.createEs2015LinkerPlugin || null;
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
}
|
|
34
|
+
return _cachedLinkerFactory;
|
|
35
|
+
}
|
|
11
36
|
// Rollup-level linker to guarantee Angular libraries are linked when included in the bundle graph.
|
|
12
37
|
function angularRollupLinker(projectRoot) {
|
|
13
38
|
let babel = null;
|
|
14
39
|
let createLinker = null;
|
|
40
|
+
let angularFileSystem = null;
|
|
15
41
|
const FILTER = /node_modules\/(?:@angular|@nativescript\/angular)\/.*\.[mc]?js$/;
|
|
16
42
|
async function ensureDeps() {
|
|
17
43
|
if (babel && createLinker)
|
|
@@ -35,6 +61,9 @@ function angularRollupLinker(projectRoot) {
|
|
|
35
61
|
}
|
|
36
62
|
catch { }
|
|
37
63
|
}
|
|
64
|
+
if (!angularFileSystem) {
|
|
65
|
+
angularFileSystem = await resolveAngularFileSystem(projectRoot);
|
|
66
|
+
}
|
|
38
67
|
}
|
|
39
68
|
return {
|
|
40
69
|
name: 'ns-angular-linker-rollup',
|
|
@@ -56,7 +85,7 @@ function angularRollupLinker(projectRoot) {
|
|
|
56
85
|
return null;
|
|
57
86
|
if (!forceLink && code.indexOf('\u0275\u0275ngDeclare') === -1 && code.indexOf('ɵɵngDeclare') === -1 && code.indexOf('ngDeclare') === -1)
|
|
58
87
|
return null;
|
|
59
|
-
const plugin = createLinker({ sourceMapping: false });
|
|
88
|
+
const plugin = createLinker({ sourceMapping: false, fileSystem: angularFileSystem });
|
|
60
89
|
if (debug) {
|
|
61
90
|
try {
|
|
62
91
|
console.log('[ns-angular-linker][rollup-load] linking', cleanId);
|
|
@@ -92,7 +121,7 @@ function angularRollupLinker(projectRoot) {
|
|
|
92
121
|
if (!babel || !createLinker)
|
|
93
122
|
return null;
|
|
94
123
|
try {
|
|
95
|
-
const plugin = createLinker({ sourceMapping: false });
|
|
124
|
+
const plugin = createLinker({ sourceMapping: false, fileSystem: angularFileSystem });
|
|
96
125
|
if (debug) {
|
|
97
126
|
try {
|
|
98
127
|
console.log('[ns-angular-linker][rollup] linking', cleanId);
|
|
@@ -126,76 +155,212 @@ let tsConfig = tsConfigAppPath;
|
|
|
126
155
|
if (!fs.existsSync(tsConfigAppPath) && fs.existsSync(tsConfigPath)) {
|
|
127
156
|
tsConfig = tsConfigPath;
|
|
128
157
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
function normalizeAngularWatchPath(filePath) {
|
|
159
|
+
return filePath
|
|
160
|
+
.split('?', 1)[0]
|
|
161
|
+
.replace(/\\/g, '/')
|
|
162
|
+
.replace(/^file:\/\//, '');
|
|
163
|
+
}
|
|
164
|
+
function normalizeAngularWatchKey(filePath) {
|
|
165
|
+
const normalizedPath = normalizeAngularWatchPath(filePath);
|
|
166
|
+
const fileSystemPath = normalizedPath.startsWith('/@fs/') ? normalizedPath.slice('/@fs'.length) : normalizedPath;
|
|
167
|
+
const normalizedProjectRoot = projectRoot.replace(/\\/g, '/').replace(/\/$/, '');
|
|
168
|
+
if (normalizedProjectRoot && fileSystemPath.startsWith(normalizedProjectRoot)) {
|
|
169
|
+
const relative = fileSystemPath.slice(normalizedProjectRoot.length);
|
|
170
|
+
return relative.startsWith('/') ? relative : `/${relative}`;
|
|
171
|
+
}
|
|
172
|
+
return fileSystemPath;
|
|
173
|
+
}
|
|
174
|
+
function getAngularWatchKeys(filePath) {
|
|
175
|
+
const normalizedPath = normalizeAngularWatchPath(filePath);
|
|
176
|
+
const keys = new Set();
|
|
177
|
+
keys.add(normalizedPath);
|
|
178
|
+
keys.add(normalizeAngularWatchKey(normalizedPath));
|
|
179
|
+
return Array.from(keys).filter(Boolean);
|
|
180
|
+
}
|
|
181
|
+
function resolveAngularWatchFilePath(filePath) {
|
|
182
|
+
const normalizedPath = normalizeAngularWatchPath(filePath);
|
|
183
|
+
const fileSystemPath = normalizedPath.startsWith('/@fs/') ? normalizedPath.slice('/@fs'.length) : normalizedPath;
|
|
184
|
+
if (path.isAbsolute(fileSystemPath) && fs.existsSync(fileSystemPath)) {
|
|
185
|
+
return fileSystemPath;
|
|
186
|
+
}
|
|
187
|
+
if (fileSystemPath.startsWith('/')) {
|
|
188
|
+
return path.resolve(projectRoot, `.${fileSystemPath}`);
|
|
189
|
+
}
|
|
190
|
+
return path.resolve(projectRoot, fileSystemPath);
|
|
191
|
+
}
|
|
192
|
+
function extractComponentAssetPaths(code, componentId) {
|
|
193
|
+
const componentPath = normalizeAngularWatchPath(componentId);
|
|
194
|
+
const assetPaths = new Set();
|
|
195
|
+
const resolveAssetPath = (assetPath) => normalizeAngularWatchPath(path.resolve(path.dirname(componentPath), assetPath));
|
|
196
|
+
const templateUrlMatch = code.match(/templateUrl\s*:\s*['"](.+?\.(?:html|htm))['"]/);
|
|
197
|
+
if (templateUrlMatch) {
|
|
198
|
+
assetPaths.add(resolveAssetPath(templateUrlMatch[1]));
|
|
199
|
+
}
|
|
200
|
+
const styleUrlMatch = code.match(/styleUrl\s*:\s*['"](.+?\.(?:css|less|sass|scss))['"]/);
|
|
201
|
+
if (styleUrlMatch) {
|
|
202
|
+
assetPaths.add(resolveAssetPath(styleUrlMatch[1]));
|
|
203
|
+
}
|
|
204
|
+
const styleUrlsMatch = code.match(/styleUrls\s*:\s*\[([\s\S]*?)\]/m);
|
|
205
|
+
if (styleUrlsMatch) {
|
|
206
|
+
for (const match of styleUrlsMatch[1].matchAll(/['"](.+?\.(?:css|less|sass|scss))['"]/g)) {
|
|
207
|
+
assetPaths.add(resolveAssetPath(match[1]));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return Array.from(assetPaths);
|
|
211
|
+
}
|
|
212
|
+
function createAngularPlugins(opts) {
|
|
213
|
+
const assetToComponents = new Map();
|
|
214
|
+
const componentToAssets = new Map();
|
|
215
|
+
const pendingComponentInvalidations = new Set();
|
|
216
|
+
const untrackComponentAssets = (componentPath) => {
|
|
217
|
+
const previousAssets = componentToAssets.get(componentPath);
|
|
218
|
+
if (!previousAssets)
|
|
219
|
+
return;
|
|
220
|
+
for (const assetPath of previousAssets) {
|
|
221
|
+
const components = assetToComponents.get(assetPath);
|
|
222
|
+
if (!components)
|
|
223
|
+
continue;
|
|
224
|
+
components.delete(componentPath);
|
|
225
|
+
if (components.size === 0) {
|
|
226
|
+
assetToComponents.delete(assetPath);
|
|
142
227
|
}
|
|
143
|
-
|
|
228
|
+
}
|
|
229
|
+
componentToAssets.delete(componentPath);
|
|
230
|
+
};
|
|
231
|
+
const trackComponentAssets = (componentPath, assetPaths) => {
|
|
232
|
+
untrackComponentAssets(componentPath);
|
|
233
|
+
if (assetPaths.length === 0)
|
|
234
|
+
return;
|
|
235
|
+
const normalizedAssets = new Set(assetPaths.flatMap((assetPath) => getAngularWatchKeys(assetPath)));
|
|
236
|
+
componentToAssets.set(componentPath, normalizedAssets);
|
|
237
|
+
for (const assetPath of normalizedAssets) {
|
|
238
|
+
const components = assetToComponents.get(assetPath) || new Set();
|
|
239
|
+
components.add(componentPath);
|
|
240
|
+
assetToComponents.set(assetPath, components);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
return [
|
|
244
|
+
// Allow external html template changes to trigger hot reload: Make .ts files depend on their .html templates
|
|
245
|
+
{
|
|
246
|
+
name: 'angular-template-deps',
|
|
247
|
+
enforce: 'pre',
|
|
248
|
+
transform(code, id) {
|
|
249
|
+
const componentPath = normalizeAngularWatchPath(id);
|
|
250
|
+
const componentKey = normalizeAngularWatchKey(id);
|
|
251
|
+
if (!componentKey.endsWith('.ts'))
|
|
252
|
+
return null;
|
|
253
|
+
const assetPaths = extractComponentAssetPaths(code, componentPath);
|
|
254
|
+
trackComponentAssets(componentKey, assetPaths);
|
|
255
|
+
for (const assetPath of assetPaths) {
|
|
256
|
+
this.addWatchFile(assetPath);
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
},
|
|
260
|
+
watchChange(id) {
|
|
261
|
+
const changedPath = normalizeAngularWatchPath(id);
|
|
262
|
+
const components = new Set();
|
|
263
|
+
for (const assetKey of getAngularWatchKeys(changedPath)) {
|
|
264
|
+
for (const componentPath of assetToComponents.get(assetKey) || []) {
|
|
265
|
+
components.add(componentPath);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (components?.size) {
|
|
269
|
+
for (const componentPath of components) {
|
|
270
|
+
pendingComponentInvalidations.add(componentPath);
|
|
271
|
+
}
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (/\.(html|htm)$/i.test(changedPath)) {
|
|
275
|
+
const componentPath = changedPath.replace(/\.(html|htm)$/i, '.ts');
|
|
276
|
+
if (fs.existsSync(resolveAngularWatchFilePath(componentPath))) {
|
|
277
|
+
pendingComponentInvalidations.add(normalizeAngularWatchKey(componentPath));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
shouldTransformCachedModule({ id }) {
|
|
282
|
+
const componentPath = normalizeAngularWatchKey(id);
|
|
283
|
+
if (!pendingComponentInvalidations.has(componentPath))
|
|
284
|
+
return null;
|
|
285
|
+
pendingComponentInvalidations.delete(componentPath);
|
|
286
|
+
return true;
|
|
287
|
+
},
|
|
144
288
|
},
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
289
|
+
// Transform Angular partial declarations in node_modules to avoid runtime JIT
|
|
290
|
+
// Pass the project root so linker deps resolve from the app, not the plugin package.
|
|
291
|
+
angularLinkerVitePlugin(process.cwd()),
|
|
292
|
+
// Simplify: rely on Vite pre plugin (load/transform) for linking; Rollup safety net disabled unless re-enabled later
|
|
293
|
+
// angularRollupLinker(process.cwd()),
|
|
294
|
+
...angular({
|
|
295
|
+
experimental: {
|
|
296
|
+
useAngularCompilationAPI: opts.useAngularCompilationAPI,
|
|
297
|
+
},
|
|
298
|
+
liveReload: false, // Disable live reload in favor of HMR
|
|
299
|
+
tsconfig: tsConfig,
|
|
300
|
+
}),
|
|
301
|
+
// Post-phase linker to catch any declarations introduced after other transforms (including project code)
|
|
302
|
+
angularLinkerVitePluginPost(process.cwd()),
|
|
303
|
+
// Enforce: fully disable dependency optimization during serve to avoid rxjs esm5 crawling and OOM
|
|
304
|
+
{
|
|
305
|
+
name: 'ns-disable-optimize-deps',
|
|
306
|
+
enforce: 'post',
|
|
307
|
+
apply: 'serve',
|
|
308
|
+
config(userConfig) {
|
|
309
|
+
const od = userConfig?.optimizeDeps || {};
|
|
310
|
+
const prevExclude = Array.isArray(od.exclude) ? od.exclude : [];
|
|
311
|
+
const exclude = new Set(prevExclude);
|
|
312
|
+
['@nativescript/core', 'rxjs', '@valor/nativescript-websockets', 'set-value', 'react', 'react-reconciler', 'react-nativescript'].forEach((x) => exclude.add(x));
|
|
313
|
+
return {
|
|
314
|
+
optimizeDeps: {
|
|
315
|
+
noDiscovery: true,
|
|
316
|
+
entries: [],
|
|
317
|
+
include: [],
|
|
318
|
+
exclude: Array.from(exclude),
|
|
319
|
+
rolldownOptions: {
|
|
320
|
+
...(od.rolldownOptions || {}),
|
|
321
|
+
plugins: [],
|
|
322
|
+
},
|
|
176
323
|
},
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
324
|
+
};
|
|
325
|
+
},
|
|
326
|
+
configResolved(resolved) {
|
|
327
|
+
const resolvedConfig = resolved;
|
|
328
|
+
const deps = (resolvedConfig.optimizeDeps || (resolvedConfig.optimizeDeps = {}));
|
|
329
|
+
deps.noDiscovery = true;
|
|
330
|
+
deps.entries = [];
|
|
331
|
+
deps.include = [];
|
|
332
|
+
const exclude = new Set(Array.isArray(deps.exclude) ? deps.exclude : []);
|
|
333
|
+
['@nativescript/core', 'rxjs', '@valor/nativescript-websockets', 'set-value', 'react', 'react-reconciler', 'react-nativescript'].forEach((x) => exclude.add(x));
|
|
334
|
+
deps.exclude = Array.from(exclude);
|
|
335
|
+
const rolldownOptions = (deps.rolldownOptions || (deps.rolldownOptions = {}));
|
|
336
|
+
rolldownOptions.plugins = [];
|
|
337
|
+
},
|
|
190
338
|
},
|
|
191
|
-
|
|
192
|
-
|
|
339
|
+
];
|
|
340
|
+
}
|
|
193
341
|
export const angularConfig = ({ mode }) => {
|
|
342
|
+
const useSingleBundleDevOutput = mode === 'development' && !hmrActive;
|
|
343
|
+
const plugins = createAngularPlugins({
|
|
344
|
+
// Vite build --watch with the legacy Analog compilation path can regress
|
|
345
|
+
// Angular app sources from Ivy output back to decorator emit on rebuild.
|
|
346
|
+
// Restrict the newer compilation API to NativeScript's development no-HMR
|
|
347
|
+
// flow, which is where the unstable rebuilds occur today.
|
|
348
|
+
useAngularCompilationAPI: useSingleBundleDevOutput,
|
|
349
|
+
});
|
|
194
350
|
const disableAnimations = true;
|
|
195
351
|
//process.env.NS_DISABLE_NG_ANIMATIONS === "1" ||
|
|
196
352
|
//process.env.NS_DISABLE_NG_ANIMATIONS === "true";
|
|
197
353
|
// Post-link emitted chunks to catch any remaining partial declarations that slipped through
|
|
198
354
|
// due to plugin order or external transforms.
|
|
355
|
+
const applyAngularChunkPostProcessing = (code, options = {}) => {
|
|
356
|
+
const codeWithInjectables = synthesizeMissingInjectableFactories(code, {
|
|
357
|
+
vendorInjectExport: options.vendorInjectExport,
|
|
358
|
+
});
|
|
359
|
+
const codeWithCtorParameters = synthesizeDecoratorCtorParameters(codeWithInjectables);
|
|
360
|
+
return inlineDecoratorComponentTemplates(codeWithCtorParameters, {
|
|
361
|
+
projectRoot: process.cwd(),
|
|
362
|
+
});
|
|
363
|
+
};
|
|
199
364
|
const postLinker = {
|
|
200
365
|
name: 'ns-angular-linker-post',
|
|
201
366
|
apply: 'build',
|
|
@@ -206,13 +371,22 @@ export const angularConfig = ({ mode }) => {
|
|
|
206
371
|
return false;
|
|
207
372
|
return Object.keys(chunk.modules).some((m) => m.includes('node_modules/@nativescript/angular/fesm2022/nativescript-angular-polyfills.mjs'));
|
|
208
373
|
}
|
|
209
|
-
const { babel
|
|
210
|
-
if (!babel
|
|
374
|
+
const { babel } = await ensureSharedAngularLinker(process.cwd());
|
|
375
|
+
if (!babel)
|
|
376
|
+
return;
|
|
377
|
+
const fileSystem = await resolveAngularFileSystem(process.cwd());
|
|
378
|
+
const linkerFactory = await importLinkerFactory();
|
|
379
|
+
if (!linkerFactory)
|
|
211
380
|
return;
|
|
212
381
|
const strict = process.env.NS_STRICT_NG_LINK === '1' || process.env.NS_STRICT_NG_LINK === 'true';
|
|
213
382
|
const enforceStrict = process.env.NS_STRICT_NG_LINK_ENFORCE === '1' || process.env.NS_STRICT_NG_LINK_ENFORCE === 'true';
|
|
214
383
|
const debug = process.env.VITE_DEBUG_LOGS === '1' || process.env.VITE_DEBUG_LOGS === 'true';
|
|
215
384
|
const unlinked = [];
|
|
385
|
+
const vendorInjectExport = (() => {
|
|
386
|
+
const vendorChunk = Object.entries(bundle).find(([name, value]) => value && value.type === 'chunk' && /(^|\/)vendor\.mjs$/.test(name));
|
|
387
|
+
const vendorCode = vendorChunk ? vendorChunk[1].code : undefined;
|
|
388
|
+
return vendorCode?.match(/\binject as ([A-Za-z_$][\w$]*)/)?.[1];
|
|
389
|
+
})();
|
|
216
390
|
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
217
391
|
if (!fileName.endsWith('.mjs') && !fileName.endsWith('.js'))
|
|
218
392
|
continue;
|
|
@@ -222,15 +396,19 @@ export const angularConfig = ({ mode }) => {
|
|
|
222
396
|
continue;
|
|
223
397
|
const isNsPolyfills = isNsAngularPolyfillsChunk(chunk);
|
|
224
398
|
try {
|
|
399
|
+
// Create a FRESH linker plugin per chunk — the linker may have
|
|
400
|
+
// internal state that becomes stale across watch-mode rebuild cycles.
|
|
401
|
+
const freshPlugin = linkerFactory({ sourceMapping: false, fileSystem });
|
|
225
402
|
const res = await babel.transformAsync(code, {
|
|
226
403
|
filename: fileName,
|
|
227
404
|
configFile: false,
|
|
228
405
|
babelrc: false,
|
|
229
406
|
sourceMaps: false,
|
|
230
407
|
compact: false,
|
|
231
|
-
plugins: [
|
|
408
|
+
plugins: [freshPlugin],
|
|
232
409
|
});
|
|
233
|
-
const
|
|
410
|
+
const linkedCode = res?.code && res.code !== code ? res.code : code;
|
|
411
|
+
const finalCode = applyAngularChunkPostProcessing(linkedCode, { vendorInjectExport });
|
|
234
412
|
if (finalCode !== code) {
|
|
235
413
|
chunk.code = finalCode;
|
|
236
414
|
if (debug) {
|
|
@@ -244,7 +422,8 @@ export const angularConfig = ({ mode }) => {
|
|
|
244
422
|
unlinked.push(fileName);
|
|
245
423
|
}
|
|
246
424
|
}
|
|
247
|
-
catch {
|
|
425
|
+
catch (e) {
|
|
426
|
+
console.warn(`[ns-angular-linker][post] linking FAILED for ${fileName}:`, e?.message || e);
|
|
248
427
|
if (strict)
|
|
249
428
|
unlinked.push(fileName);
|
|
250
429
|
}
|
|
@@ -290,37 +469,46 @@ export const angularConfig = ({ mode }) => {
|
|
|
290
469
|
}
|
|
291
470
|
},
|
|
292
471
|
};
|
|
293
|
-
// Safety net: transform each rendered chunk to link any remaining ɵɵngDeclare* call sites
|
|
472
|
+
// Safety net: transform each rendered chunk to link any remaining ɵɵngDeclare* call sites.
|
|
473
|
+
// IMPORTANT: create a FRESH linker plugin per invocation — the shared instance may have
|
|
474
|
+
// stale internal state from a prior build cycle, causing silent failures in watch-mode rebuilds.
|
|
294
475
|
const renderChunkLinker = {
|
|
295
476
|
name: 'ns-angular-linker-render',
|
|
296
477
|
apply: 'build',
|
|
297
478
|
enforce: 'post',
|
|
298
479
|
async renderChunk(code, chunk) {
|
|
480
|
+
if (!code)
|
|
481
|
+
return null;
|
|
482
|
+
const filename = chunk.fileName || chunk.name || 'chunk.mjs';
|
|
483
|
+
const debug = process.env.VITE_DEBUG_LOGS === '1' || process.env.VITE_DEBUG_LOGS === 'true';
|
|
299
484
|
try {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
485
|
+
let transformed = code;
|
|
486
|
+
if (containsRealNgDeclare(code)) {
|
|
487
|
+
const { babel } = await ensureSharedAngularLinker(process.cwd());
|
|
488
|
+
if (!babel)
|
|
489
|
+
return null;
|
|
490
|
+
const fileSystem = await resolveAngularFileSystem(process.cwd());
|
|
491
|
+
// Fresh plugin per chunk — avoids stale linker state across watch-mode rebuilds
|
|
492
|
+
const freshPlugin = (await importLinkerFactory())?.({ sourceMapping: false, fileSystem });
|
|
493
|
+
if (!freshPlugin)
|
|
494
|
+
return null;
|
|
495
|
+
const runLink = async (input) => {
|
|
496
|
+
const result = await babel.transformAsync(input, {
|
|
497
|
+
filename,
|
|
498
|
+
configFile: false,
|
|
499
|
+
babelrc: false,
|
|
500
|
+
sourceMaps: false,
|
|
501
|
+
compact: false,
|
|
502
|
+
plugins: [freshPlugin],
|
|
503
|
+
});
|
|
504
|
+
return result?.code ?? input;
|
|
505
|
+
};
|
|
506
|
+
transformed = await runLink(code);
|
|
507
|
+
if (containsRealNgDeclare(transformed)) {
|
|
508
|
+
transformed = await runLink(transformed);
|
|
509
|
+
}
|
|
323
510
|
}
|
|
511
|
+
transformed = applyAngularChunkPostProcessing(transformed);
|
|
324
512
|
if (transformed !== code) {
|
|
325
513
|
if (debug) {
|
|
326
514
|
try {
|
|
@@ -331,40 +519,42 @@ export const angularConfig = ({ mode }) => {
|
|
|
331
519
|
return { code: transformed, map: null };
|
|
332
520
|
}
|
|
333
521
|
}
|
|
334
|
-
catch {
|
|
522
|
+
catch (e) {
|
|
523
|
+
console.warn(`[ns-angular-linker][render] linking FAILED for ${filename}:`, e?.message || e);
|
|
524
|
+
}
|
|
335
525
|
return null;
|
|
336
526
|
},
|
|
337
527
|
};
|
|
338
528
|
const enableRollupLinker = process.env.NS_ENABLE_ROLLUP_LINKER === '1' || process.env.NS_ENABLE_ROLLUP_LINKER === 'true' || hmrActive;
|
|
339
|
-
|
|
529
|
+
// Build a single merged alias array to avoid property override conflicts.
|
|
530
|
+
// Previously the disableAnimations spread added a second `resolve` key
|
|
531
|
+
// that silently clobbered the fesm2022 and RxJS aliases.
|
|
532
|
+
const angularAliases = [
|
|
533
|
+
// Map Angular deep ESM paths to bare package ids
|
|
534
|
+
{ find: /^@angular\/([^/]+)\/fesm2022\/.*\.mjs$/, replacement: '@angular/$1' },
|
|
535
|
+
{ find: /^@nativescript\/angular\/fesm2022\/.*\.mjs$/, replacement: '@nativescript/angular' },
|
|
536
|
+
// RxJS esm5 → esm redirects removed: Vite 8 enforces the rxjs `exports` field,
|
|
537
|
+
// blocking deep path aliases. Instead, the `es2015` resolve condition is added
|
|
538
|
+
// below so rxjs resolves to its modern ESM builds via the exports map.
|
|
539
|
+
];
|
|
540
|
+
if (disableAnimations) {
|
|
541
|
+
angularAliases.push({
|
|
542
|
+
find: /^@angular\/animations(\/.+)?$/, // match subpaths too
|
|
543
|
+
replacement: resolveRelativeToImportMeta(import.meta.url, '../shims/angular-animations-stub.js'),
|
|
544
|
+
}, {
|
|
545
|
+
find: /^@angular\/platform-browser\/animations(\/.+)?$/,
|
|
546
|
+
replacement: resolveRelativeToImportMeta(import.meta.url, '../shims/angular-animations-stub.js'),
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
const config = mergeConfig(baseConfig({ mode, flavor: 'angular' }), {
|
|
340
550
|
plugins: [...plugins, ...(enableRollupLinker ? [angularRollupLinker(process.cwd())] : []), renderChunkLinker, postLinker],
|
|
341
|
-
// Always alias fesm2022 deep imports to package root so vendor bridge can externalize properly
|
|
342
551
|
resolve: {
|
|
343
|
-
alias:
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
{ find: /^rxjs\/dist\/esm5\/(.*)$/, replacement: 'rxjs/dist/esm2015/$1' },
|
|
349
|
-
{ find: /^rxjs\/operators$/, replacement: 'rxjs/dist/esm2015/operators/index.js' },
|
|
350
|
-
{ find: /^rxjs$/, replacement: 'rxjs/dist/esm2015/index.js' },
|
|
351
|
-
// Existing optional animations shims
|
|
352
|
-
],
|
|
552
|
+
alias: angularAliases,
|
|
553
|
+
// Add 'es2015' condition so RxJS resolves to dist/esm (modern ESM) rather
|
|
554
|
+
// than dist/esm5 via the 'default' condition. This avoids the esm5 module
|
|
555
|
+
// explosion and OOM while respecting the package's exports field in Vite 8.
|
|
556
|
+
conditions: ['es2015'],
|
|
353
557
|
},
|
|
354
|
-
...(disableAnimations && {
|
|
355
|
-
resolve: {
|
|
356
|
-
alias: [
|
|
357
|
-
{
|
|
358
|
-
find: /^@angular\/animations(\/.+)?$/, // match subpaths too
|
|
359
|
-
replacement: new URL('../shims/angular-animations-stub.js', import.meta.url).pathname,
|
|
360
|
-
},
|
|
361
|
-
{
|
|
362
|
-
find: /^@angular\/platform-browser\/animations(\/.+)?$/,
|
|
363
|
-
replacement: new URL('../shims/angular-animations-stub.js', import.meta.url).pathname,
|
|
364
|
-
},
|
|
365
|
-
],
|
|
366
|
-
},
|
|
367
|
-
}),
|
|
368
558
|
// Disable dependency optimization entirely for NativeScript Angular HMR.
|
|
369
559
|
// Vite 5.1+: use noDiscovery with an empty include list (disabled was removed).
|
|
370
560
|
// The HTTP loader + vendor bridge manage dependencies; pre-bundling can OOM.
|
|
@@ -376,5 +566,19 @@ export const angularConfig = ({ mode }) => {
|
|
|
376
566
|
rolldownOptions: { plugins: [] },
|
|
377
567
|
},
|
|
378
568
|
});
|
|
569
|
+
if (useSingleBundleDevOutput) {
|
|
570
|
+
const build = (config.build ?? (config.build = {}));
|
|
571
|
+
const rolldownOptions = (build.rolldownOptions ?? (build.rolldownOptions = {}));
|
|
572
|
+
const outputConfigs = Array.isArray(rolldownOptions.output) ? rolldownOptions.output : [rolldownOptions.output ?? {}];
|
|
573
|
+
for (const output of outputConfigs) {
|
|
574
|
+
// Angular non-HMR reloads are more reliable when rebuilds keep a single boot bundle.
|
|
575
|
+
// This avoids watch-time chunk alias/name drift that can leave the native app reloading into stale split points.
|
|
576
|
+
delete output.manualChunks;
|
|
577
|
+
delete output.chunkFileNames;
|
|
578
|
+
output.codeSplitting = false;
|
|
579
|
+
}
|
|
580
|
+
rolldownOptions.output = Array.isArray(rolldownOptions.output) ? outputConfigs : outputConfigs[0];
|
|
581
|
+
}
|
|
582
|
+
return config;
|
|
379
583
|
};
|
|
380
584
|
//# sourceMappingURL=angular.js.map
|