@nativescript/vite 8.0.0-alpha.2 → 8.0.0-alpha.21
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 +34 -1
- package/configuration/angular.js +380 -34
- package/configuration/angular.js.map +1 -1
- package/configuration/base.js +171 -7
- package/configuration/base.js.map +1 -1
- package/configuration/solid.js +27 -1
- package/configuration/solid.js.map +1 -1
- package/configuration/typescript.js +1 -1
- package/configuration/typescript.js.map +1 -1
- package/helpers/angular/angular-linker.js +3 -12
- package/helpers/angular/angular-linker.js.map +1 -1
- package/helpers/angular/inject-component-hmr-registration.d.ts +112 -0
- package/helpers/angular/inject-component-hmr-registration.js +359 -0
- package/helpers/angular/inject-component-hmr-registration.js.map +1 -0
- package/helpers/angular/inject-hmr-vite-ignore.d.ts +75 -0
- package/helpers/angular/inject-hmr-vite-ignore.js +288 -0
- package/helpers/angular/inject-hmr-vite-ignore.js.map +1 -0
- package/helpers/angular/util.d.ts +1 -0
- package/helpers/angular/util.js +88 -0
- package/helpers/angular/util.js.map +1 -1
- 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/config-as-json.js +10 -0
- package/helpers/config-as-json.js.map +1 -1
- package/helpers/dev-host.d.ts +274 -0
- package/helpers/dev-host.js +491 -0
- package/helpers/dev-host.js.map +1 -0
- package/helpers/global-defines.d.ts +51 -0
- package/helpers/global-defines.js +77 -0
- package/helpers/global-defines.js.map +1 -1
- package/helpers/logging.d.ts +1 -0
- package/helpers/logging.js +63 -3
- package/helpers/logging.js.map +1 -1
- package/helpers/main-entry.d.ts +3 -1
- package/helpers/main-entry.js +450 -125
- package/helpers/main-entry.js.map +1 -1
- package/helpers/nativeclass-transformer-plugin.d.ts +9 -2
- package/helpers/nativeclass-transformer-plugin.js +157 -14
- package/helpers/nativeclass-transformer-plugin.js.map +1 -1
- package/helpers/ns-core-url.d.ts +88 -0
- package/helpers/ns-core-url.js +191 -0
- package/helpers/ns-core-url.js.map +1 -0
- package/helpers/prelink-angular.js +1 -4
- package/helpers/prelink-angular.js.map +1 -1
- package/helpers/project.d.ts +35 -0
- package/helpers/project.js +120 -2
- package/helpers/project.js.map +1 -1
- package/helpers/resolver.js +9 -1
- package/helpers/resolver.js.map +1 -1
- package/helpers/solid-jsx-deps.d.ts +15 -0
- package/helpers/solid-jsx-deps.js +178 -0
- package/helpers/solid-jsx-deps.js.map +1 -0
- package/helpers/ts-config-paths.js +50 -2
- package/helpers/ts-config-paths.js.map +1 -1
- package/helpers/workers.d.ts +20 -19
- package/helpers/workers.js +620 -3
- package/helpers/workers.js.map +1 -1
- package/hmr/client/css-handler.d.ts +1 -0
- package/hmr/client/css-handler.js +34 -5
- package/hmr/client/css-handler.js.map +1 -1
- package/hmr/client/css-update-overlay.d.ts +18 -0
- package/hmr/client/css-update-overlay.js +27 -0
- package/hmr/client/css-update-overlay.js.map +1 -0
- package/hmr/client/hmr-pending-overlay.d.ts +27 -0
- package/hmr/client/hmr-pending-overlay.js +50 -0
- package/hmr/client/hmr-pending-overlay.js.map +1 -0
- package/hmr/client/index.js +491 -34
- package/hmr/client/index.js.map +1 -1
- package/hmr/client/utils.d.ts +5 -0
- package/hmr/client/utils.js +283 -12
- package/hmr/client/utils.js.map +1 -1
- package/hmr/client/vue-sfc-update-overlay.d.ts +82 -0
- package/hmr/client/vue-sfc-update-overlay.js +133 -0
- package/hmr/client/vue-sfc-update-overlay.js.map +1 -0
- package/hmr/entry-runtime.d.ts +2 -1
- package/hmr/entry-runtime.js +253 -66
- package/hmr/entry-runtime.js.map +1 -1
- package/hmr/frameworks/angular/client/index.d.ts +3 -1
- package/hmr/frameworks/angular/client/index.js +802 -10
- package/hmr/frameworks/angular/client/index.js.map +1 -1
- package/hmr/frameworks/angular/server/linker.js +1 -4
- package/hmr/frameworks/angular/server/linker.js.map +1 -1
- package/hmr/frameworks/angular/server/strategy.js +30 -6
- 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/frameworks/vue/client/index.js +30 -45
- package/hmr/frameworks/vue/client/index.js.map +1 -1
- package/hmr/helpers/ast-normalizer.js +52 -5
- package/hmr/helpers/ast-normalizer.js.map +1 -1
- package/hmr/helpers/cjs-named-exports.d.ts +23 -0
- package/hmr/helpers/cjs-named-exports.js +152 -0
- package/hmr/helpers/cjs-named-exports.js.map +1 -0
- package/hmr/helpers/package-exports.d.ts +16 -0
- package/hmr/helpers/package-exports.js +396 -0
- package/hmr/helpers/package-exports.js.map +1 -0
- package/hmr/server/constants.js +13 -4
- package/hmr/server/constants.js.map +1 -1
- package/hmr/server/core-sanitize.d.ts +93 -8
- package/hmr/server/core-sanitize.js +222 -49
- package/hmr/server/core-sanitize.js.map +1 -1
- package/hmr/server/import-map.js +80 -22
- package/hmr/server/import-map.js.map +1 -1
- package/hmr/server/index.d.ts +2 -1
- package/hmr/server/index.js.map +1 -1
- package/hmr/server/ns-core-cjs-shape.d.ts +204 -0
- package/hmr/server/ns-core-cjs-shape.js +271 -0
- package/hmr/server/ns-core-cjs-shape.js.map +1 -0
- package/hmr/server/ns-rt-bridge.d.ts +51 -0
- package/hmr/server/ns-rt-bridge.js +131 -0
- package/hmr/server/ns-rt-bridge.js.map +1 -0
- package/hmr/server/perf-instrumentation.d.ts +114 -0
- package/hmr/server/perf-instrumentation.js +195 -0
- package/hmr/server/perf-instrumentation.js.map +1 -0
- 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 +144 -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 +497 -58
- 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 +78 -0
- package/hmr/server/websocket-angular-hot-update.js +413 -0
- package/hmr/server/websocket-angular-hot-update.js.map +1 -0
- package/hmr/server/websocket-core-bridge.d.ts +58 -0
- package/hmr/server/websocket-core-bridge.js +368 -0
- package/hmr/server/websocket-core-bridge.js.map +1 -0
- package/hmr/server/websocket-css-hot-update.d.ts +33 -0
- package/hmr/server/websocket-css-hot-update.js +65 -0
- package/hmr/server/websocket-css-hot-update.js.map +1 -0
- package/hmr/server/websocket-graph-upsert.d.ts +21 -0
- package/hmr/server/websocket-graph-upsert.js +33 -0
- package/hmr/server/websocket-graph-upsert.js.map +1 -0
- package/hmr/server/websocket-hmr-pending.d.ts +43 -0
- package/hmr/server/websocket-hmr-pending.js +55 -0
- package/hmr/server/websocket-hmr-pending.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 +101 -0
- package/hmr/server/websocket-module-specifiers.js +820 -0
- package/hmr/server/websocket-module-specifiers.js.map +1 -0
- package/hmr/server/websocket-ns-m-finalize.d.ts +22 -0
- package/hmr/server/websocket-ns-m-finalize.js +88 -0
- package/hmr/server/websocket-ns-m-finalize.js.map +1 -0
- package/hmr/server/websocket-ns-m-paths.d.ts +3 -0
- package/hmr/server/websocket-ns-m-paths.js +92 -0
- package/hmr/server/websocket-ns-m-paths.js.map +1 -0
- package/hmr/server/websocket-ns-m-request.d.ts +45 -0
- package/hmr/server/websocket-ns-m-request.js +196 -0
- package/hmr/server/websocket-ns-m-request.js.map +1 -0
- package/hmr/server/websocket-served-module-helpers.d.ts +36 -0
- package/hmr/server/websocket-served-module-helpers.js +644 -0
- package/hmr/server/websocket-served-module-helpers.js.map +1 -0
- package/hmr/server/websocket-txn.d.ts +6 -0
- package/hmr/server/websocket-txn.js +45 -0
- package/hmr/server/websocket-txn.js.map +1 -0
- package/hmr/server/websocket-vendor-unifier.d.ts +10 -0
- package/hmr/server/websocket-vendor-unifier.js +51 -0
- package/hmr/server/websocket-vendor-unifier.js.map +1 -0
- package/hmr/server/websocket-vue-sfc.d.ts +26 -0
- package/hmr/server/websocket-vue-sfc.js +1053 -0
- package/hmr/server/websocket-vue-sfc.js.map +1 -0
- package/hmr/server/websocket.d.ts +58 -75
- package/hmr/server/websocket.js +2232 -1802
- 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/boot-placeholder-ui.d.ts +69 -0
- package/hmr/shared/runtime/boot-placeholder-ui.js +101 -0
- package/hmr/shared/runtime/boot-placeholder-ui.js.map +1 -0
- package/hmr/shared/runtime/boot-progress.d.ts +40 -0
- package/hmr/shared/runtime/boot-progress.js +128 -0
- package/hmr/shared/runtime/boot-progress.js.map +1 -0
- package/hmr/shared/runtime/boot-timeline.d.ts +18 -0
- package/hmr/shared/runtime/boot-timeline.js +52 -0
- package/hmr/shared/runtime/boot-timeline.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 +78 -3
- package/hmr/shared/runtime/dev-overlay.js +1094 -26
- package/hmr/shared/runtime/dev-overlay.js.map +1 -1
- package/hmr/shared/runtime/module-provenance.js +1 -4
- package/hmr/shared/runtime/module-provenance.js.map +1 -1
- package/hmr/shared/runtime/root-placeholder.d.ts +1 -0
- package/hmr/shared/runtime/root-placeholder.js +1019 -151
- 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 +309 -0
- package/hmr/shared/runtime/session-bootstrap.js.map +1 -0
- package/hmr/shared/runtime/vendor-bootstrap.js +1 -9
- package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
- package/hmr/shared/vendor/manifest.d.ts +32 -0
- package/hmr/shared/vendor/manifest.js +411 -46
- package/hmr/shared/vendor/manifest.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/package.json +9 -1
- package/runtime/core-aliases-early.js +94 -67
- package/runtime/core-aliases-early.js.map +1 -1
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
import { type UserConfig } from 'vite';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* File replacement entry forwarded to `@analogjs/vite-plugin-angular`.
|
|
4
|
+
* `replace` and `with` may be absolute paths or paths relative to
|
|
5
|
+
* `workspaceRoot` (when supplied). The Analog plugin matches against the
|
|
6
|
+
* resolved id with `endsWith(replace)`, so absolute paths Just Work in Nx
|
|
7
|
+
* / pnpm / Rush layouts where the source tree may live above the project
|
|
8
|
+
* root.
|
|
9
|
+
*/
|
|
10
|
+
export interface AngularFileReplacement {
|
|
11
|
+
replace: string;
|
|
12
|
+
with: string;
|
|
13
|
+
ssr?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const angularConfig: ({ mode, fileReplacements, workspaceRoot, }: {
|
|
3
16
|
mode: string;
|
|
17
|
+
/**
|
|
18
|
+
* Angular CLI–style file replacements (e.g. `environment.ts` →
|
|
19
|
+
* `environment.stg.ts`) forwarded to `@analogjs/vite-plugin-angular`'s
|
|
20
|
+
* `replaceFiles` plugin AND to the Angular TypeScript CompilerHost.
|
|
21
|
+
*
|
|
22
|
+
* Required for monorepo apps that need configuration-specific
|
|
23
|
+
* environment files: the Angular host reads source files via its own
|
|
24
|
+
* file-system layer, so a Vite `resolveId`/`load` plugin alone cannot
|
|
25
|
+
* swap a `.ts` file for `vite serve` / HMR — the host will still
|
|
26
|
+
* compile the original source from disk. Passing the list here ensures
|
|
27
|
+
* the host sees the replacement before TypeScript ever parses the
|
|
28
|
+
* file, matching how Angular CLI's `fileReplacements` works.
|
|
29
|
+
*/
|
|
30
|
+
fileReplacements?: AngularFileReplacement[];
|
|
31
|
+
/**
|
|
32
|
+
* Workspace root used by `@analogjs/vite-plugin-angular` to resolve
|
|
33
|
+
* relative `fileReplacements` paths. Absolute paths bypass this.
|
|
34
|
+
* Defaults to `process.cwd()`.
|
|
35
|
+
*/
|
|
36
|
+
workspaceRoot?: string;
|
|
4
37
|
}) => UserConfig;
|
package/configuration/angular.js
CHANGED
|
@@ -7,11 +7,14 @@ import { angularLinkerVitePlugin, angularLinkerVitePluginPost } from '../helpers
|
|
|
7
7
|
import { synthesizeMissingInjectableFactories } from '../helpers/angular/synthesize-injectable-factories.js';
|
|
8
8
|
import { ensureSharedAngularLinker, resolveAngularFileSystem } from '../helpers/angular/shared-linker.js';
|
|
9
9
|
import { inlineDecoratorComponentTemplates } from '../helpers/angular/inline-decorator-component-templates.js';
|
|
10
|
+
import { appendComponentHmrRegistration, findComponentClassNames, INJECTION_MARKER as HMR_REGISTER_MARKER } from '../helpers/angular/inject-component-hmr-registration.js';
|
|
11
|
+
import { injectAngularHmrViteIgnore } from '../helpers/angular/inject-hmr-vite-ignore.js';
|
|
10
12
|
import { synthesizeDecoratorCtorParameters } from '../helpers/angular/synthesize-decorator-ctor-parameters.js';
|
|
11
|
-
import { containsRealNgDeclare } from '../helpers/angular/util.js';
|
|
13
|
+
import { containsRealNgDeclare, stripJsComments } from '../helpers/angular/util.js';
|
|
12
14
|
import { baseConfig } from './base.js';
|
|
13
15
|
import { getCliFlags } from '../helpers/cli-flags.js';
|
|
14
16
|
import { resolveRelativeToImportMeta } from '../helpers/import-meta-path.js';
|
|
17
|
+
import { resolveVerboseFlag } from '../helpers/logging.js';
|
|
15
18
|
// Lazily import the Angular linker factory function. Used by chunk-level linkers
|
|
16
19
|
// to create FRESH plugin instances per invocation (avoiding stale state in watch mode).
|
|
17
20
|
let _cachedLinkerFactory = null;
|
|
@@ -87,10 +90,7 @@ function angularRollupLinker(projectRoot) {
|
|
|
87
90
|
return null;
|
|
88
91
|
const plugin = createLinker({ sourceMapping: false, fileSystem: angularFileSystem });
|
|
89
92
|
if (debug) {
|
|
90
|
-
|
|
91
|
-
console.log('[ns-angular-linker][rollup-load] linking', cleanId);
|
|
92
|
-
}
|
|
93
|
-
catch { }
|
|
93
|
+
console.log('[ns-angular-linker][rollup-load] linking', cleanId);
|
|
94
94
|
}
|
|
95
95
|
const result = await babel.transformAsync(code, {
|
|
96
96
|
filename: cleanId,
|
|
@@ -123,10 +123,7 @@ function angularRollupLinker(projectRoot) {
|
|
|
123
123
|
try {
|
|
124
124
|
const plugin = createLinker({ sourceMapping: false, fileSystem: angularFileSystem });
|
|
125
125
|
if (debug) {
|
|
126
|
-
|
|
127
|
-
console.log('[ns-angular-linker][rollup] linking', cleanId);
|
|
128
|
-
}
|
|
129
|
-
catch { }
|
|
126
|
+
console.log('[ns-angular-linker][rollup] linking', cleanId);
|
|
130
127
|
}
|
|
131
128
|
const result = await babel.transformAsync(code, {
|
|
132
129
|
filename: cleanId,
|
|
@@ -148,6 +145,37 @@ function angularRollupLinker(projectRoot) {
|
|
|
148
145
|
const cliFlags = getCliFlags();
|
|
149
146
|
const isDevEnv = process.env.NODE_ENV !== 'production';
|
|
150
147
|
const hmrActive = isDevEnv && !!cliFlags.hmr;
|
|
148
|
+
/**
|
|
149
|
+
* Web-style template HMR opt-out.
|
|
150
|
+
*
|
|
151
|
+
* When `hmrActive` is true we default to the in-place template-replacement
|
|
152
|
+
* pipeline (`liveReload: true` on Analog → `_enableHmr: true` on the Angular
|
|
153
|
+
* TS compiler → `angular:component-update` events served via the
|
|
154
|
+
* `/@ng/component` middleware → `ɵɵreplaceMetadata` on the live class).
|
|
155
|
+
* Setting `_enableHmr: true` also forces Analog to set
|
|
156
|
+
* `externalRuntimeStyles: true`, changing how component styles are emitted
|
|
157
|
+
* (URLs fetched lazily instead of inlined). On the web that's fine; for
|
|
158
|
+
* NativeScript it's a new code path that touches the SCSS / Tailwind
|
|
159
|
+
* pipeline and the iOS runtime's HTTP module loader.
|
|
160
|
+
*
|
|
161
|
+
* If a project hits a regression on day one (broken styling, unresolved
|
|
162
|
+
* `?ngcomp=` imports, etc.) the user can roll back to the legacy reboot
|
|
163
|
+
* pipeline without an upstream patch by setting the env flag. We honour
|
|
164
|
+
* `0`, `false`, `off`, and `no` (case-insensitive) as "off" — anything
|
|
165
|
+
* else (including unset) keeps the new path on.
|
|
166
|
+
*
|
|
167
|
+
* The flag is read once at module load, mirroring how `hmrActive` is
|
|
168
|
+
* computed, so a project can flip it via `cross-env` in their dev script
|
|
169
|
+
* and never look back.
|
|
170
|
+
*/
|
|
171
|
+
const angularLiveReloadDisabledByEnv = (() => {
|
|
172
|
+
const raw = process.env.NS_VITE_ANGULAR_LIVE_RELOAD;
|
|
173
|
+
if (typeof raw !== 'string')
|
|
174
|
+
return false;
|
|
175
|
+
const v = raw.trim().toLowerCase();
|
|
176
|
+
return v === '0' || v === 'false' || v === 'off' || v === 'no';
|
|
177
|
+
})();
|
|
178
|
+
const hmrAngularLiveReload = hmrActive && !angularLiveReloadDisabledByEnv;
|
|
151
179
|
const projectRoot = process.cwd();
|
|
152
180
|
const tsConfigAppPath = path.resolve(projectRoot, 'tsconfig.app.json');
|
|
153
181
|
const tsConfigPath = path.resolve(projectRoot, 'tsconfig.json');
|
|
@@ -156,21 +184,61 @@ if (!fs.existsSync(tsConfigAppPath) && fs.existsSync(tsConfigPath)) {
|
|
|
156
184
|
tsConfig = tsConfigPath;
|
|
157
185
|
}
|
|
158
186
|
function normalizeAngularWatchPath(filePath) {
|
|
159
|
-
return filePath
|
|
187
|
+
return filePath
|
|
188
|
+
.split('?', 1)[0]
|
|
189
|
+
.replace(/\\/g, '/')
|
|
190
|
+
.replace(/^file:\/\//, '');
|
|
191
|
+
}
|
|
192
|
+
function normalizeAngularWatchKey(filePath) {
|
|
193
|
+
const normalizedPath = normalizeAngularWatchPath(filePath);
|
|
194
|
+
const fileSystemPath = normalizedPath.startsWith('/@fs/') ? normalizedPath.slice('/@fs'.length) : normalizedPath;
|
|
195
|
+
const normalizedProjectRoot = projectRoot.replace(/\\/g, '/').replace(/\/$/, '');
|
|
196
|
+
if (normalizedProjectRoot && fileSystemPath.startsWith(normalizedProjectRoot)) {
|
|
197
|
+
const relative = fileSystemPath.slice(normalizedProjectRoot.length);
|
|
198
|
+
return relative.startsWith('/') ? relative : `/${relative}`;
|
|
199
|
+
}
|
|
200
|
+
return fileSystemPath;
|
|
201
|
+
}
|
|
202
|
+
function getAngularWatchKeys(filePath) {
|
|
203
|
+
const normalizedPath = normalizeAngularWatchPath(filePath);
|
|
204
|
+
const keys = new Set();
|
|
205
|
+
keys.add(normalizedPath);
|
|
206
|
+
keys.add(normalizeAngularWatchKey(normalizedPath));
|
|
207
|
+
return Array.from(keys).filter(Boolean);
|
|
208
|
+
}
|
|
209
|
+
function resolveAngularWatchFilePath(filePath) {
|
|
210
|
+
const normalizedPath = normalizeAngularWatchPath(filePath);
|
|
211
|
+
const fileSystemPath = normalizedPath.startsWith('/@fs/') ? normalizedPath.slice('/@fs'.length) : normalizedPath;
|
|
212
|
+
if (path.isAbsolute(fileSystemPath) && fs.existsSync(fileSystemPath)) {
|
|
213
|
+
return fileSystemPath;
|
|
214
|
+
}
|
|
215
|
+
if (fileSystemPath.startsWith('/')) {
|
|
216
|
+
return path.resolve(projectRoot, `.${fileSystemPath}`);
|
|
217
|
+
}
|
|
218
|
+
return path.resolve(projectRoot, fileSystemPath);
|
|
160
219
|
}
|
|
161
220
|
function extractComponentAssetPaths(code, componentId) {
|
|
162
221
|
const componentPath = normalizeAngularWatchPath(componentId);
|
|
163
222
|
const assetPaths = new Set();
|
|
164
223
|
const resolveAssetPath = (assetPath) => normalizeAngularWatchPath(path.resolve(path.dirname(componentPath), assetPath));
|
|
165
|
-
|
|
224
|
+
// Blank out `//` and `/* */` comments before scanning. The regexes below
|
|
225
|
+
// are intentionally simple (no JS parser) so they would otherwise match
|
|
226
|
+
// commented-out `templateUrl` / `styleUrls` declarations and register
|
|
227
|
+
// phantom asset deps via `addWatchFile`. In current Rolldown-Vite that
|
|
228
|
+
// also enrolls them as `_addedImports`, which `vite:import-analysis`
|
|
229
|
+
// then tries to resolve — surfacing as a misleading
|
|
230
|
+
// `Failed to resolve import "<file>" from "<importer>". Does the file
|
|
231
|
+
// exist?` pre-transform error if the file (predictably) doesn't exist.
|
|
232
|
+
const scanCode = stripJsComments(code);
|
|
233
|
+
const templateUrlMatch = scanCode.match(/templateUrl\s*:\s*['"](.+?\.(?:html|htm))['"]/);
|
|
166
234
|
if (templateUrlMatch) {
|
|
167
235
|
assetPaths.add(resolveAssetPath(templateUrlMatch[1]));
|
|
168
236
|
}
|
|
169
|
-
const styleUrlMatch =
|
|
237
|
+
const styleUrlMatch = scanCode.match(/styleUrl\s*:\s*['"](.+?\.(?:css|less|sass|scss))['"]/);
|
|
170
238
|
if (styleUrlMatch) {
|
|
171
239
|
assetPaths.add(resolveAssetPath(styleUrlMatch[1]));
|
|
172
240
|
}
|
|
173
|
-
const styleUrlsMatch =
|
|
241
|
+
const styleUrlsMatch = scanCode.match(/styleUrls\s*:\s*\[([\s\S]*?)\]/m);
|
|
174
242
|
if (styleUrlsMatch) {
|
|
175
243
|
for (const match of styleUrlsMatch[1].matchAll(/['"](.+?\.(?:css|less|sass|scss))['"]/g)) {
|
|
176
244
|
assetPaths.add(resolveAssetPath(match[1]));
|
|
@@ -179,9 +247,18 @@ function extractComponentAssetPaths(code, componentId) {
|
|
|
179
247
|
return Array.from(assetPaths);
|
|
180
248
|
}
|
|
181
249
|
function createAngularPlugins(opts) {
|
|
250
|
+
const verbose = resolveVerboseFlag();
|
|
182
251
|
const assetToComponents = new Map();
|
|
183
252
|
const componentToAssets = new Map();
|
|
184
253
|
const pendingComponentInvalidations = new Set();
|
|
254
|
+
// Shared state between the `enforce: 'pre'` discovery plugin and the
|
|
255
|
+
// `enforce: 'post'` injection plugin. Maps a clean (no-querystring)
|
|
256
|
+
// .ts file id to the list of `@Component`-decorated class names found
|
|
257
|
+
// in its RAW TypeScript source. The pre plugin populates this map;
|
|
258
|
+
// the post plugin reads it to know which class names to register
|
|
259
|
+
// against the compiled output. Cleared on each pre-plugin invocation
|
|
260
|
+
// so renames or `@Component` removals don't leave stale entries.
|
|
261
|
+
const componentsByCleanId = new Map();
|
|
185
262
|
const untrackComponentAssets = (componentPath) => {
|
|
186
263
|
const previousAssets = componentToAssets.get(componentPath);
|
|
187
264
|
if (!previousAssets)
|
|
@@ -201,7 +278,7 @@ function createAngularPlugins(opts) {
|
|
|
201
278
|
untrackComponentAssets(componentPath);
|
|
202
279
|
if (assetPaths.length === 0)
|
|
203
280
|
return;
|
|
204
|
-
const normalizedAssets = new Set(assetPaths.
|
|
281
|
+
const normalizedAssets = new Set(assetPaths.flatMap((assetPath) => getAngularWatchKeys(assetPath)));
|
|
205
282
|
componentToAssets.set(componentPath, normalizedAssets);
|
|
206
283
|
for (const assetPath of normalizedAssets) {
|
|
207
284
|
const components = assetToComponents.get(assetPath) || new Set();
|
|
@@ -209,43 +286,190 @@ function createAngularPlugins(opts) {
|
|
|
209
286
|
assetToComponents.set(assetPath, components);
|
|
210
287
|
}
|
|
211
288
|
};
|
|
289
|
+
const isCandidateComponentTs = (cleanId) => {
|
|
290
|
+
if (!cleanId.endsWith('.ts'))
|
|
291
|
+
return false;
|
|
292
|
+
if (cleanId.includes('/node_modules/'))
|
|
293
|
+
return false;
|
|
294
|
+
if (cleanId.endsWith('.d.ts'))
|
|
295
|
+
return false;
|
|
296
|
+
if (cleanId.endsWith('.spec.ts') || cleanId.endsWith('.test.ts'))
|
|
297
|
+
return false;
|
|
298
|
+
return true;
|
|
299
|
+
};
|
|
212
300
|
return [
|
|
301
|
+
// HMR self-registration runs in two phases:
|
|
302
|
+
//
|
|
303
|
+
// 1. (this plugin, `enforce: 'pre'`) Walk the raw TypeScript
|
|
304
|
+
// source for each user `.ts` file and record the names of
|
|
305
|
+
// any `@Component`-decorated classes into the shared
|
|
306
|
+
// `componentsByCleanId` map. Discovery has to happen on the
|
|
307
|
+
// raw source because the Analog Angular plugin rewrites
|
|
308
|
+
// `@Component(...)` into static metadata calls and removes
|
|
309
|
+
// the textual decorator pattern.
|
|
310
|
+
//
|
|
311
|
+
// 2. (`ns-component-hmr-register-post`, `enforce: 'post'`)
|
|
312
|
+
// After the Analog Angular plugin has compiled the file,
|
|
313
|
+
// append the global `__NS_HMR_REGISTER_COMPONENT__`
|
|
314
|
+
// registration calls keyed by the names recorded in step 1.
|
|
315
|
+
//
|
|
316
|
+
// Why the two-phase split: the Analog Angular plugin's `transform`
|
|
317
|
+
// returns its OWN regenerated compiled output (from its internal
|
|
318
|
+
// `outputFiles` cache populated at `buildStart`), discarding any
|
|
319
|
+
// code modifications applied earlier in the pipeline. We
|
|
320
|
+
// previously appended the registration snippet here, in the pre
|
|
321
|
+
// plugin, and the snippet was silently dropped — leaving the
|
|
322
|
+
// HMR class registry empty and `getFreshComponentClass` returning
|
|
323
|
+
// `found=false reason=no-registry` after every reboot.
|
|
324
|
+
//
|
|
325
|
+
// Placement notes that still apply:
|
|
326
|
+
// - `apply: 'serve'`: the registry runtime hook is dev-only;
|
|
327
|
+
// production builds never need self-registration.
|
|
328
|
+
// - Intentionally NOT gated on `hmrActive`. The injected
|
|
329
|
+
// snippet self-guards with
|
|
330
|
+
// `typeof globalThis.__NS_HMR_REGISTER_COMPONENT__ === 'function'`,
|
|
331
|
+
// so it's a no-op when the runtime hook isn't installed
|
|
332
|
+
// (e.g. `--no-hmr` users still serving modules through
|
|
333
|
+
// Vite). Gating the transform itself on `hmrActive` produced
|
|
334
|
+
// a silent failure mode where `--no-hmr` users got HMR
|
|
335
|
+
// machinery up but never got the registration calls
|
|
336
|
+
// injected, leaving the registry empty.
|
|
337
|
+
{
|
|
338
|
+
name: 'ns-component-hmr-register',
|
|
339
|
+
enforce: 'pre',
|
|
340
|
+
apply: 'serve',
|
|
341
|
+
transform(code, id) {
|
|
342
|
+
const cleanId = id.split('?', 1)[0];
|
|
343
|
+
if (!isCandidateComponentTs(cleanId))
|
|
344
|
+
return null;
|
|
345
|
+
const componentNames = findComponentClassNames(code);
|
|
346
|
+
if (componentNames.length === 0) {
|
|
347
|
+
// Drop any stale entry from a previous transform
|
|
348
|
+
// pass; the file may have lost its `@Component`
|
|
349
|
+
// decorator across a rename/refactor.
|
|
350
|
+
componentsByCleanId.delete(cleanId);
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
componentsByCleanId.set(cleanId, componentNames);
|
|
354
|
+
if (verbose) {
|
|
355
|
+
console.info(`[ns-hmr][ns-component-hmr-register] discovered ${componentNames.length} component(s) in ${cleanId} (${componentNames.join(', ')})`);
|
|
356
|
+
}
|
|
357
|
+
// Discovery only — never modify the raw TS source. Any
|
|
358
|
+
// modification here is discarded by the Analog Angular
|
|
359
|
+
// plugin downstream; the actual snippet append happens
|
|
360
|
+
// in `ns-component-hmr-register-post`.
|
|
361
|
+
return null;
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
// Phase 2: append the HMR registration snippet to the compiled
|
|
365
|
+
// JS output produced by `@analogjs/vite-plugin-angular`. Runs
|
|
366
|
+
// `enforce: 'post'` so we see the post-Angular code (where the
|
|
367
|
+
// pre plugin's work would otherwise be discarded). Reads the
|
|
368
|
+
// component names recorded by the pre plugin via
|
|
369
|
+
// `componentsByCleanId`.
|
|
370
|
+
{
|
|
371
|
+
name: 'ns-component-hmr-register-post',
|
|
372
|
+
enforce: 'post',
|
|
373
|
+
apply: 'serve',
|
|
374
|
+
transform(code, id) {
|
|
375
|
+
const cleanId = id.split('?', 1)[0];
|
|
376
|
+
if (!isCandidateComponentTs(cleanId))
|
|
377
|
+
return null;
|
|
378
|
+
const componentNames = componentsByCleanId.get(cleanId);
|
|
379
|
+
if (!componentNames || componentNames.length === 0)
|
|
380
|
+
return null;
|
|
381
|
+
// Idempotency: the Vite cache may replay the transform
|
|
382
|
+
// pipeline on cached modules. The marker comment is
|
|
383
|
+
// inserted by `appendComponentHmrRegistration` and
|
|
384
|
+
// guards against double-injection. We also defensively
|
|
385
|
+
// short-circuit here so we don't have to allocate the
|
|
386
|
+
// suffix string on every cached re-run.
|
|
387
|
+
if (code.includes(HMR_REGISTER_MARKER))
|
|
388
|
+
return null;
|
|
389
|
+
const result = appendComponentHmrRegistration(code, componentNames);
|
|
390
|
+
if (!result.code)
|
|
391
|
+
return null;
|
|
392
|
+
if (verbose) {
|
|
393
|
+
console.info(`[ns-hmr][ns-component-hmr-register-post] appended registrations for ${result.componentNames.length} component(s) in ${cleanId} (${result.componentNames.join(', ')})`);
|
|
394
|
+
}
|
|
395
|
+
// Returning `null` for the source map is acceptable for
|
|
396
|
+
// dev: lines 1..N (the original compiled body) keep
|
|
397
|
+
// the upstream Angular source map; the appended snippet
|
|
398
|
+
// is invisible to debuggers but harmless. For
|
|
399
|
+
// production-grade source maps a MagicString-based
|
|
400
|
+
// pass-through could be used; not required for HMR.
|
|
401
|
+
return { code: result.code, map: null };
|
|
402
|
+
},
|
|
403
|
+
},
|
|
213
404
|
// Allow external html template changes to trigger hot reload: Make .ts files depend on their .html templates
|
|
214
405
|
{
|
|
215
406
|
name: 'angular-template-deps',
|
|
216
407
|
enforce: 'pre',
|
|
217
408
|
transform(code, id) {
|
|
218
409
|
const componentPath = normalizeAngularWatchPath(id);
|
|
219
|
-
|
|
410
|
+
const componentKey = normalizeAngularWatchKey(id);
|
|
411
|
+
if (!componentKey.endsWith('.ts'))
|
|
220
412
|
return null;
|
|
221
413
|
const assetPaths = extractComponentAssetPaths(code, componentPath);
|
|
222
|
-
trackComponentAssets(
|
|
414
|
+
trackComponentAssets(componentKey, assetPaths);
|
|
223
415
|
for (const assetPath of assetPaths) {
|
|
224
416
|
this.addWatchFile(assetPath);
|
|
225
417
|
}
|
|
418
|
+
// Diagnostic: surface which .ts files we've registered
|
|
419
|
+
// asset (template/styleUrls) dependencies for. This is
|
|
420
|
+
// the first fence the HTML→TS invalidation pipeline must
|
|
421
|
+
// pass — if we never see a [tracking] log for the
|
|
422
|
+
// component we're editing, the watcher will never fire
|
|
423
|
+
// and `pendingComponentInvalidations` stays empty.
|
|
424
|
+
if (verbose) {
|
|
425
|
+
console.info(`[ns-hmr][angular-template-deps] [tracking] componentKey=${componentKey} assets=${assetPaths.length} (${assetPaths.slice(0, 4).join(', ')})`);
|
|
426
|
+
}
|
|
226
427
|
return null;
|
|
227
428
|
},
|
|
228
429
|
watchChange(id) {
|
|
229
430
|
const changedPath = normalizeAngularWatchPath(id);
|
|
230
|
-
const components =
|
|
431
|
+
const components = new Set();
|
|
432
|
+
for (const assetKey of getAngularWatchKeys(changedPath)) {
|
|
433
|
+
for (const componentPath of assetToComponents.get(assetKey) || []) {
|
|
434
|
+
components.add(componentPath);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
231
437
|
if (components?.size) {
|
|
232
438
|
for (const componentPath of components) {
|
|
233
439
|
pendingComponentInvalidations.add(componentPath);
|
|
234
440
|
}
|
|
441
|
+
if (verbose) {
|
|
442
|
+
console.info(`[ns-hmr][angular-template-deps] watchChange [via assetToComponents] changed=${changedPath} → invalidating ${components.size} component(s):`, Array.from(components));
|
|
443
|
+
}
|
|
235
444
|
return;
|
|
236
445
|
}
|
|
237
446
|
if (/\.(html|htm)$/i.test(changedPath)) {
|
|
238
447
|
const componentPath = changedPath.replace(/\.(html|htm)$/i, '.ts');
|
|
239
|
-
|
|
240
|
-
|
|
448
|
+
const exists = fs.existsSync(resolveAngularWatchFilePath(componentPath));
|
|
449
|
+
if (exists) {
|
|
450
|
+
const componentKey = normalizeAngularWatchKey(componentPath);
|
|
451
|
+
pendingComponentInvalidations.add(componentKey);
|
|
452
|
+
if (verbose) {
|
|
453
|
+
console.info(`[ns-hmr][angular-template-deps] watchChange [via fallback .html→.ts] changed=${changedPath} componentKey=${componentKey}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
// Truly anomalous: a watched template/style asset has no companion
|
|
458
|
+
// `.ts` file, so we cannot route the edit through the Angular
|
|
459
|
+
// HMR pipeline. Always-on warning so it surfaces in non-verbose
|
|
460
|
+
// runs — silent fallback would hide a real wiring break.
|
|
461
|
+
console.warn(`[ns-hmr][angular-template-deps] watchChange [no companion .ts found] changed=${changedPath} expectedTs=${componentPath}`);
|
|
241
462
|
}
|
|
242
463
|
}
|
|
243
464
|
},
|
|
244
465
|
shouldTransformCachedModule({ id }) {
|
|
245
|
-
const componentPath =
|
|
466
|
+
const componentPath = normalizeAngularWatchKey(id);
|
|
246
467
|
if (!pendingComponentInvalidations.has(componentPath))
|
|
247
468
|
return null;
|
|
248
469
|
pendingComponentInvalidations.delete(componentPath);
|
|
470
|
+
if (verbose) {
|
|
471
|
+
console.info(`[ns-hmr][angular-template-deps] shouldTransformCachedModule → re-transform componentKey=${componentPath}`);
|
|
472
|
+
}
|
|
249
473
|
return true;
|
|
250
474
|
},
|
|
251
475
|
},
|
|
@@ -258,11 +482,140 @@ function createAngularPlugins(opts) {
|
|
|
258
482
|
experimental: {
|
|
259
483
|
useAngularCompilationAPI: opts.useAngularCompilationAPI,
|
|
260
484
|
},
|
|
261
|
-
liveReload
|
|
485
|
+
// `liveReload` is Analog's flag for Angular's web-style template HMR
|
|
486
|
+
// pipeline. When ON, Analog:
|
|
487
|
+
// 1. Sets `_enableHmr = true` on the TS compiler so each compiled
|
|
488
|
+
// component `.mjs` emits `<ClassName>_HmrLoad` plus an
|
|
489
|
+
// `import.meta.hot.on('angular:component-update', ...)` listener.
|
|
490
|
+
// 2. Registers a `/@ng/component?c=<id>` middleware that serves the
|
|
491
|
+
// recompiled template's `_UpdateMetadata` source on demand.
|
|
492
|
+
// 3. In `handleHotUpdate` for `.html` / `.css` / `.scss` edits, sends
|
|
493
|
+
// `server.ws.send('angular:component-update', { id, timestamp })`
|
|
494
|
+
// so the runtime can call `ɵɵreplaceMetadata` on the live class —
|
|
495
|
+
// swapping the template definition AND walking live LViews to
|
|
496
|
+
// recreate matching views in-place. NO Angular reboot, NO route
|
|
497
|
+
// navigation.
|
|
498
|
+
//
|
|
499
|
+
// Previously this was `false` because the NativeScript HMR pipeline
|
|
500
|
+
// rebuilt every save through `__reboot_ng_modules__`. That works but
|
|
501
|
+
// has two big downsides on mobile: every save triggers a full app
|
|
502
|
+
// reboot AND the captured route-history replay (see
|
|
503
|
+
// `@nativescript/angular`'s `hmr-route-replay.ts`), which produces 2-3
|
|
504
|
+
// re-navigations per save and re-instantiates the page component
|
|
505
|
+
// multiple times. For pure template/style edits — the common case —
|
|
506
|
+
// the web-style component-replacement path keeps the page mounted and
|
|
507
|
+
// only swaps the changed bits.
|
|
508
|
+
//
|
|
509
|
+
// We only enable this when HMR itself is active (`hmrActive` already
|
|
510
|
+
// gates on `--hmr` and `NODE_ENV !== 'production'`). With HMR off the
|
|
511
|
+
// behaviour is unchanged: production builds and `--no-hmr` dev still
|
|
512
|
+
// see `liveReload: false`, the compiler skips the HMR initializers,
|
|
513
|
+
// and the middleware is not registered.
|
|
514
|
+
//
|
|
515
|
+
// Important interactions to be aware of:
|
|
516
|
+
// - When `_enableHmr` is true, Analog also sets
|
|
517
|
+
// `externalRuntimeStyles = true`, changing how component styles
|
|
518
|
+
// are emitted (URLs fetched at runtime instead of inlined). For
|
|
519
|
+
// NativeScript, the existing CSS pipeline expects inlined styles;
|
|
520
|
+
// `ns-component-hmr-style-overrides` (below) restores the
|
|
521
|
+
// pre-HMR style-emission strategy so Tailwind/global SCSS
|
|
522
|
+
// packaging keeps working.
|
|
523
|
+
// - The runtime dynamic-import resolves the metadata URL relative
|
|
524
|
+
// to `import.meta.url`, e.g. `http://host:port/ns/m/<componentDir>/@ng/component?c=...`.
|
|
525
|
+
// Analog's middleware uses `req.url.includes('/@ng/component')`
|
|
526
|
+
// (substring match), so the request still matches even with the
|
|
527
|
+
// `/ns/m/` prefix in the path.
|
|
528
|
+
// - The NS HMR client (`packages/vite/hmr/client/index.ts`)
|
|
529
|
+
// forwards Vite's standard `{ type: 'custom', event, data }`
|
|
530
|
+
// payloads to `import.meta.hot.on` listeners via
|
|
531
|
+
// `__NS_DISPATCH_HOT_EVENT__`, and short-circuits before the
|
|
532
|
+
// reboot path for `angular:component-update`.
|
|
533
|
+
// - The NS server-side hot-update handler in
|
|
534
|
+
// `packages/vite/hmr/server/websocket.ts` skips its own
|
|
535
|
+
// `ns:angular-update` broadcast for `.html` / component-style
|
|
536
|
+
// edits so we don't double-fire (the reboot path stays for `.ts`
|
|
537
|
+
// edits).
|
|
538
|
+
// - To roll back to the legacy reboot-only pipeline (e.g. while
|
|
539
|
+
// debugging an `externalRuntimeStyles` regression), set
|
|
540
|
+
// `NS_VITE_ANGULAR_LIVE_RELOAD=0` in the dev environment.
|
|
541
|
+
// `hmrAngularLiveReload` collapses both gates above.
|
|
542
|
+
liveReload: hmrAngularLiveReload,
|
|
543
|
+
// NativeScript can't consume Angular's `externalRuntimeStyles`
|
|
544
|
+
// mode — that emits component styles as runtime-loaded
|
|
545
|
+
// `<hash>.css` URL references which only a browser CSSOM/`<link>`
|
|
546
|
+
// pipeline can resolve. We tell our patched Analog plugin (see
|
|
547
|
+
// `patches/@analogjs+vite-plugin-angular+2.3.1.patch` in
|
|
548
|
+
// downstream apps; upstream PR pending) to keep the legacy
|
|
549
|
+
// behavior of inlining preprocessed CSS strings into the
|
|
550
|
+
// component metadata's `styles: [...]` array, which the NS
|
|
551
|
+
// renderer's CSS-bundle pipeline already knows how to apply.
|
|
552
|
+
// The option is independent from `liveReload` (`_enableHmr`
|
|
553
|
+
// still wires up `ɵɵreplaceMetadata` for in-place template
|
|
554
|
+
// HMR) — we keep HMR ON, just opt out of the URL-style
|
|
555
|
+
// emission. Note the option lands as a no-op on stock
|
|
556
|
+
// Analog releases that haven't merged the patch; once
|
|
557
|
+
// merged, this will switch the compiler off external styles
|
|
558
|
+
// for NativeScript without affecting web builds.
|
|
559
|
+
//
|
|
560
|
+
// `@ts-expect-error` because the option is not yet in
|
|
561
|
+
// `@analogjs/vite-plugin-angular`'s published `PluginOptions`
|
|
562
|
+
// type. When the upstream PR (https://github.com/analogjs/analog)
|
|
563
|
+
// adds it, this `@ts-expect-error` will itself become an
|
|
564
|
+
// "unused suppression" error — that's the signal to remove
|
|
565
|
+
// this comment AND the surrounding explanation, and bump
|
|
566
|
+
// the Analog peer dep to the version that ships the type.
|
|
567
|
+
// @ts-expect-error -- pending upstream Analog type publish
|
|
568
|
+
externalRuntimeStyles: false,
|
|
262
569
|
tsconfig: tsConfig,
|
|
570
|
+
// Forward Angular-style file replacements (e.g. `environment.ts`
|
|
571
|
+
// → `environment.stg.ts`) directly into the Analog plugin so the
|
|
572
|
+
// Angular TypeScript host (which reads source files via its own
|
|
573
|
+
// CompilerHost, bypassing Vite's load chain) sees the swap. This
|
|
574
|
+
// is the same hook Angular CLI uses for `fileReplacements` in
|
|
575
|
+
// `angular.json` build configurations.
|
|
576
|
+
fileReplacements: opts.fileReplacements ?? [],
|
|
577
|
+
workspaceRoot: opts.workspaceRoot ?? process.cwd(),
|
|
263
578
|
}),
|
|
264
579
|
// Post-phase linker to catch any declarations introduced after other transforms (including project code)
|
|
265
580
|
angularLinkerVitePluginPost(process.cwd()),
|
|
581
|
+
// Re-inject the `/* @vite-ignore */` annotation onto Angular's HMR
|
|
582
|
+
// initializer dynamic imports.
|
|
583
|
+
//
|
|
584
|
+
// Angular's compiler emits each component's HMR loader as
|
|
585
|
+
// `import(/* @vite-ignore */ i0.ɵɵgetReplaceMetadataURL(...))` so
|
|
586
|
+
// Vite leaves the runtime-computed URL alone. The annotation goes
|
|
587
|
+
// missing somewhere in the post-Angular pipeline (empirically the
|
|
588
|
+
// linker's `compact: false` Babel pass loses it on some files),
|
|
589
|
+
// causing Vite's static analyzer to flag the import and rewrite
|
|
590
|
+
// the call site through its runtime resolver — which then throws
|
|
591
|
+
// `TypeError at ɵɵgetReplaceMetadataURL` on the iOS device because
|
|
592
|
+
// the resolver expects a statically known specifier.
|
|
593
|
+
//
|
|
594
|
+
// Running `enforce: 'post'` and `apply: 'serve'` here ensures we
|
|
595
|
+
// see the file AFTER every other transform has had its chance to
|
|
596
|
+
// strip comments, AND only in dev (the HMR initializer is gated
|
|
597
|
+
// behind `ngDevMode` and never runs in a production build, so the
|
|
598
|
+
// fix would be wasted work outside `serve`). The helper is
|
|
599
|
+
// idempotent: if the annotation is already present, the file is
|
|
600
|
+
// returned unchanged.
|
|
601
|
+
{
|
|
602
|
+
name: 'ns-angular-hmr-vite-ignore',
|
|
603
|
+
enforce: 'post',
|
|
604
|
+
apply: 'serve',
|
|
605
|
+
transform(code, id) {
|
|
606
|
+
if (!hmrAngularLiveReload)
|
|
607
|
+
return null;
|
|
608
|
+
const cleanId = id.split('?', 1)[0];
|
|
609
|
+
if (!cleanId.endsWith('.ts') && !cleanId.endsWith('.mjs') && !cleanId.endsWith('.js'))
|
|
610
|
+
return null;
|
|
611
|
+
if (cleanId.includes('/node_modules/'))
|
|
612
|
+
return null;
|
|
613
|
+
const next = injectAngularHmrViteIgnore(code);
|
|
614
|
+
if (next === code)
|
|
615
|
+
return null;
|
|
616
|
+
return { code: next, map: null };
|
|
617
|
+
},
|
|
618
|
+
},
|
|
266
619
|
// Enforce: fully disable dependency optimization during serve to avoid rxjs esm5 crawling and OOM
|
|
267
620
|
{
|
|
268
621
|
name: 'ns-disable-optimize-deps',
|
|
@@ -301,7 +654,7 @@ function createAngularPlugins(opts) {
|
|
|
301
654
|
},
|
|
302
655
|
];
|
|
303
656
|
}
|
|
304
|
-
export const angularConfig = ({ mode }) => {
|
|
657
|
+
export const angularConfig = ({ mode, fileReplacements, workspaceRoot, }) => {
|
|
305
658
|
const useSingleBundleDevOutput = mode === 'development' && !hmrActive;
|
|
306
659
|
const plugins = createAngularPlugins({
|
|
307
660
|
// Vite build --watch with the legacy Analog compilation path can regress
|
|
@@ -309,6 +662,8 @@ export const angularConfig = ({ mode }) => {
|
|
|
309
662
|
// Restrict the newer compilation API to NativeScript's development no-HMR
|
|
310
663
|
// flow, which is where the unstable rebuilds occur today.
|
|
311
664
|
useAngularCompilationAPI: useSingleBundleDevOutput,
|
|
665
|
+
fileReplacements,
|
|
666
|
+
workspaceRoot,
|
|
312
667
|
});
|
|
313
668
|
const disableAnimations = true;
|
|
314
669
|
//process.env.NS_DISABLE_NG_ANIMATIONS === "1" ||
|
|
@@ -375,10 +730,7 @@ export const angularConfig = ({ mode }) => {
|
|
|
375
730
|
if (finalCode !== code) {
|
|
376
731
|
chunk.code = finalCode;
|
|
377
732
|
if (debug) {
|
|
378
|
-
|
|
379
|
-
console.log('[ns-angular-linker][post] linked', fileName, isNsPolyfills ? '(polyfills)' : '');
|
|
380
|
-
}
|
|
381
|
-
catch { }
|
|
733
|
+
console.log('[ns-angular-linker][post] linked', fileName, isNsPolyfills ? '(polyfills)' : '');
|
|
382
734
|
}
|
|
383
735
|
}
|
|
384
736
|
if (strict && !isNsPolyfills && containsRealNgDeclare(finalCode)) {
|
|
@@ -424,10 +776,7 @@ export const angularConfig = ({ mode }) => {
|
|
|
424
776
|
throw new Error(message);
|
|
425
777
|
}
|
|
426
778
|
else {
|
|
427
|
-
|
|
428
|
-
console.warn(`[ns-angular-linker-post] ${message}`);
|
|
429
|
-
}
|
|
430
|
-
catch { }
|
|
779
|
+
console.warn(`[ns-angular-linker-post] ${message}`);
|
|
431
780
|
}
|
|
432
781
|
}
|
|
433
782
|
},
|
|
@@ -474,10 +823,7 @@ export const angularConfig = ({ mode }) => {
|
|
|
474
823
|
transformed = applyAngularChunkPostProcessing(transformed);
|
|
475
824
|
if (transformed !== code) {
|
|
476
825
|
if (debug) {
|
|
477
|
-
|
|
478
|
-
console.log('[ns-angular-linker][render] linked', filename);
|
|
479
|
-
}
|
|
480
|
-
catch { }
|
|
826
|
+
console.log('[ns-angular-linker][render] linked', filename);
|
|
481
827
|
}
|
|
482
828
|
return { code: transformed, map: null };
|
|
483
829
|
}
|