@analogjs/vite-plugin-angular 3.0.0-alpha.7 → 3.0.0-alpha.70
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/README.md +30 -0
- package/migrations/migrate-setup-vitest/migrate-setup-vitest.d.ts +2 -0
- package/migrations/migrate-setup-vitest/migrate-setup-vitest.js +49 -0
- package/migrations/migrate-setup-vitest/migrate-setup-vitest.js.map +1 -0
- package/migrations/migration.json +7 -1
- package/migrations/migrations.json +9 -0
- package/migrations/update-3-0-0/migrate-setup-vitest.d.ts +2 -0
- package/migrations/update-3-0-0/migrate-setup-vitest.js +36 -0
- package/migrations/update-3-0-0/migrate-setup-vitest.js.map +1 -0
- package/package.json +51 -12
- package/src/index.d.ts +3 -2
- package/src/index.js +6 -2
- package/src/index.js.map +1 -1
- package/src/lib/angular-build-optimizer-plugin.d.ts +4 -4
- package/src/lib/angular-build-optimizer-plugin.js +57 -62
- package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
- package/src/lib/angular-jit-plugin.d.ts +3 -3
- package/src/lib/angular-jit-plugin.js +40 -37
- package/src/lib/angular-jit-plugin.js.map +1 -1
- package/src/lib/angular-pending-tasks.plugin.d.ts +7 -7
- package/src/lib/angular-pending-tasks.plugin.js +17 -18
- package/src/lib/angular-pending-tasks.plugin.js.map +1 -1
- package/src/lib/angular-vite-plugin.d.ts +180 -69
- package/src/lib/angular-vite-plugin.js +1307 -1083
- package/src/lib/angular-vite-plugin.js.map +1 -1
- package/src/lib/angular-vitest-plugin.d.ts +26 -17
- package/src/lib/angular-vitest-plugin.js +106 -114
- package/src/lib/angular-vitest-plugin.js.map +1 -1
- package/src/lib/compilation-api/compilation-api-plugin.d.ts +29 -0
- package/src/lib/compilation-api/compilation-api-plugin.js +488 -0
- package/src/lib/compilation-api/compilation-api-plugin.js.map +1 -0
- package/src/lib/compilation-api/index.d.ts +1 -0
- package/src/lib/compilation-api/index.js +1 -0
- package/src/lib/compiler/angular-version.d.ts +19 -0
- package/src/lib/compiler/angular-version.js +31 -0
- package/src/lib/compiler/angular-version.js.map +1 -0
- package/src/lib/compiler/class-field-lowering.d.ts +23 -0
- package/src/lib/compiler/class-field-lowering.js +131 -0
- package/src/lib/compiler/class-field-lowering.js.map +1 -0
- package/src/lib/compiler/compile.d.ts +50 -0
- package/src/lib/compiler/compile.js +814 -0
- package/src/lib/compiler/compile.js.map +1 -0
- package/src/lib/compiler/constants.d.ts +24 -0
- package/src/lib/compiler/constants.js +59 -0
- package/src/lib/compiler/constants.js.map +1 -0
- package/src/lib/compiler/debug.d.ts +22 -0
- package/src/lib/compiler/debug.js +20 -0
- package/src/lib/compiler/debug.js.map +1 -0
- package/src/lib/compiler/defer.d.ts +57 -0
- package/src/lib/compiler/defer.js +154 -0
- package/src/lib/compiler/defer.js.map +1 -0
- package/src/lib/compiler/dts-reader.d.ts +45 -0
- package/src/lib/compiler/dts-reader.js +395 -0
- package/src/lib/compiler/dts-reader.js.map +1 -0
- package/src/lib/compiler/hmr.d.ts +16 -0
- package/src/lib/compiler/hmr.js +69 -0
- package/src/lib/compiler/hmr.js.map +1 -0
- package/src/lib/compiler/index.d.ts +8 -0
- package/src/lib/compiler/index.js +8 -0
- package/src/lib/compiler/jit-metadata.d.ts +14 -0
- package/src/lib/compiler/jit-metadata.js +168 -0
- package/src/lib/compiler/jit-metadata.js.map +1 -0
- package/src/lib/compiler/jit-transform.d.ts +24 -0
- package/src/lib/compiler/jit-transform.js +204 -0
- package/src/lib/compiler/jit-transform.js.map +1 -0
- package/src/lib/compiler/js-emitter.d.ts +10 -0
- package/src/lib/compiler/js-emitter.js +446 -0
- package/src/lib/compiler/js-emitter.js.map +1 -0
- package/src/lib/compiler/metadata.d.ts +36 -0
- package/src/lib/compiler/metadata.js +710 -0
- package/src/lib/compiler/metadata.js.map +1 -0
- package/src/lib/compiler/registry.d.ts +56 -0
- package/src/lib/compiler/registry.js +176 -0
- package/src/lib/compiler/registry.js.map +1 -0
- package/src/lib/compiler/resource-inliner.d.ts +43 -0
- package/src/lib/compiler/resource-inliner.js +230 -0
- package/src/lib/compiler/resource-inliner.js.map +1 -0
- package/src/lib/compiler/style-ast.d.ts +9 -0
- package/src/lib/compiler/style-ast.js +54 -0
- package/src/lib/compiler/style-ast.js.map +1 -0
- package/src/lib/compiler/styles.d.ts +13 -0
- package/src/lib/compiler/test-helpers.d.ts +7 -0
- package/src/lib/compiler/type-elision.d.ts +28 -0
- package/src/lib/compiler/type-elision.js +211 -0
- package/src/lib/compiler/type-elision.js.map +1 -0
- package/src/lib/compiler/utils.d.ts +40 -0
- package/src/lib/compiler/utils.js +76 -0
- package/src/lib/compiler/utils.js.map +1 -0
- package/src/lib/compiler-plugin.d.ts +13 -12
- package/src/lib/compiler-plugin.js +40 -44
- package/src/lib/compiler-plugin.js.map +1 -1
- package/src/lib/component-resolvers.d.ts +23 -5
- package/src/lib/component-resolvers.js +152 -63
- package/src/lib/component-resolvers.js.map +1 -1
- package/src/lib/encapsulation-plugin.d.ts +13 -0
- package/src/lib/encapsulation-plugin.js +48 -0
- package/src/lib/encapsulation-plugin.js.map +1 -0
- package/src/lib/fast-compile-plugin.d.ts +28 -0
- package/src/lib/fast-compile-plugin.js +414 -0
- package/src/lib/fast-compile-plugin.js.map +1 -0
- package/src/lib/host.d.ts +10 -8
- package/src/lib/host.js +113 -101
- package/src/lib/host.js.map +1 -1
- package/src/lib/live-reload-plugin.d.ts +5 -5
- package/src/lib/live-reload-plugin.js +61 -63
- package/src/lib/live-reload-plugin.js.map +1 -1
- package/src/lib/models.d.ts +9 -9
- package/src/lib/nx-folder-plugin.d.ts +5 -5
- package/src/lib/nx-folder-plugin.js +18 -16
- package/src/lib/nx-folder-plugin.js.map +1 -1
- package/src/lib/plugins/file-replacements.plugin.d.ts +4 -4
- package/src/lib/plugins/file-replacements.plugin.js +40 -62
- package/src/lib/plugins/file-replacements.plugin.js.map +1 -1
- package/src/lib/router-plugin.d.ts +1 -1
- package/src/lib/router-plugin.js +35 -23
- package/src/lib/router-plugin.js.map +1 -1
- package/src/lib/style-pipeline.d.ts +15 -0
- package/src/lib/style-pipeline.js +31 -0
- package/src/lib/style-pipeline.js.map +1 -0
- package/src/lib/style-preprocessor.d.ts +35 -0
- package/src/lib/style-preprocessor.js +35 -0
- package/src/lib/style-preprocessor.js.map +1 -0
- package/src/lib/stylesheet-registry.d.ts +74 -0
- package/src/lib/stylesheet-registry.js +174 -0
- package/src/lib/stylesheet-registry.js.map +1 -0
- package/src/lib/tailwind-plugin.d.ts +34 -0
- package/src/lib/tailwind-plugin.js +116 -0
- package/src/lib/tailwind-plugin.js.map +1 -0
- package/src/lib/template-class-binding-guard-plugin.d.ts +30 -0
- package/src/lib/template-class-binding-guard-plugin.js +237 -0
- package/src/lib/template-class-binding-guard-plugin.js.map +1 -0
- package/src/lib/tools/package.json +2 -7
- package/src/lib/tools/src/builders/vite/vite-build.impl.js +33 -38
- package/src/lib/tools/src/builders/vite/vite-build.impl.js.map +1 -1
- package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js +51 -62
- package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js.map +1 -1
- package/src/lib/tools/src/index.js +0 -2
- package/src/lib/utils/compilation-shared.d.ts +62 -0
- package/src/lib/utils/compilation-shared.js +138 -0
- package/src/lib/utils/compilation-shared.js.map +1 -0
- package/src/lib/utils/compiler-plugin-options.d.ts +11 -11
- package/src/lib/utils/css-extension-resolver.d.ts +32 -0
- package/src/lib/utils/css-extension-resolver.js +73 -0
- package/src/lib/utils/css-extension-resolver.js.map +1 -0
- package/src/lib/utils/debug-harness.d.ts +23 -0
- package/src/lib/utils/debug-harness.js +88 -0
- package/src/lib/utils/debug-harness.js.map +1 -0
- package/src/lib/utils/debug-log-file.d.ts +5 -0
- package/src/lib/utils/debug-log-file.js +56 -0
- package/src/lib/utils/debug-log-file.js.map +1 -0
- package/src/lib/utils/debug.d.ts +28 -0
- package/src/lib/utils/debug.js +39 -0
- package/src/lib/utils/debug.js.map +1 -0
- package/src/lib/utils/devkit.d.ts +6 -6
- package/src/lib/utils/devkit.js +34 -38
- package/src/lib/utils/devkit.js.map +1 -1
- package/src/lib/utils/hmr-candidates.d.ts +28 -28
- package/src/lib/utils/jit-inline-styles.d.ts +3 -0
- package/src/lib/utils/jit-inline-styles.js +16 -0
- package/src/lib/utils/jit-inline-styles.js.map +1 -0
- package/src/lib/utils/plugin-config.d.ts +41 -0
- package/src/lib/utils/plugin-config.js +85 -0
- package/src/lib/utils/plugin-config.js.map +1 -0
- package/src/lib/utils/rolldown.d.ts +2 -0
- package/src/lib/utils/rolldown.js +12 -0
- package/src/lib/utils/rolldown.js.map +1 -0
- package/src/lib/utils/safe-module-paths.d.ts +16 -0
- package/src/lib/utils/safe-module-paths.js +29 -0
- package/src/lib/utils/safe-module-paths.js.map +1 -0
- package/src/lib/utils/source-file-cache.d.ts +8 -15
- package/src/lib/utils/source-file-cache.js +35 -37
- package/src/lib/utils/source-file-cache.js.map +1 -1
- package/src/lib/utils/tailwind-reference.d.ts +12 -0
- package/src/lib/utils/tailwind-reference.js +99 -0
- package/src/lib/utils/tailwind-reference.js.map +1 -0
- package/src/lib/utils/transform-cache.d.ts +43 -0
- package/src/lib/utils/transform-cache.js +97 -0
- package/src/lib/utils/transform-cache.js.map +1 -0
- package/src/lib/utils/tsconfig-resolver.d.ts +28 -0
- package/src/lib/utils/tsconfig-resolver.js +191 -0
- package/src/lib/utils/tsconfig-resolver.js.map +1 -0
- package/src/lib/utils/virtual-ids.d.ts +4 -0
- package/src/lib/utils/virtual-ids.js +23 -0
- package/src/lib/utils/virtual-ids.js.map +1 -0
- package/src/lib/utils/virtual-resources.d.ts +19 -0
- package/src/lib/utils/virtual-resources.js +38 -0
- package/src/lib/utils/virtual-resources.js.map +1 -0
- package/src/lib/virtual-modules-plugin.d.ts +5 -0
- package/src/lib/virtual-modules-plugin.js +23 -0
- package/src/lib/virtual-modules-plugin.js.map +1 -0
- package/src/test-setup.d.ts +2 -0
- package/setup-vitest.d.ts +0 -4
- package/setup-vitest.js +0 -215
- package/setup-vitest.js.map +0 -1
- package/src/lib/models.js +0 -1
- package/src/lib/models.js.map +0 -1
- package/src/lib/tools/README.md +0 -3
- package/src/lib/tools/src/index.d.ts +0 -0
- package/src/lib/tools/src/index.js.map +0 -1
- package/src/lib/utils/compiler-plugin-options.js +0 -1
- package/src/lib/utils/compiler-plugin-options.js.map +0 -1
- package/src/lib/utils/hmr-candidates.js +0 -272
- package/src/lib/utils/hmr-candidates.js.map +0 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { debugStylesV } from "./utils/debug.js";
|
|
2
|
+
import * as ngCompiler from "@angular/compiler";
|
|
3
|
+
//#region packages/vite-plugin-angular/src/lib/encapsulation-plugin.ts
|
|
4
|
+
function isComponentStyleSheet(id) {
|
|
5
|
+
return id.includes("ngcomp=");
|
|
6
|
+
}
|
|
7
|
+
function getComponentStyleSheetMeta(id) {
|
|
8
|
+
const params = new URL(id, "http://localhost").searchParams;
|
|
9
|
+
return {
|
|
10
|
+
componentId: params.get("ngcomp"),
|
|
11
|
+
encapsulation: {
|
|
12
|
+
"0": "emulated",
|
|
13
|
+
"2": "none",
|
|
14
|
+
"3": "shadow"
|
|
15
|
+
}[params.get("e")]
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Encapsulation runs in enforce: 'post' so that @tailwindcss/vite
|
|
20
|
+
* (enforce: 'pre') fully resolves @apply directives — including those
|
|
21
|
+
* inside :host {} — before Angular's ShadowCss rewrites selectors.
|
|
22
|
+
* (#2293)
|
|
23
|
+
*/
|
|
24
|
+
function encapsulationPlugin(shouldExternalizeStyles) {
|
|
25
|
+
return {
|
|
26
|
+
name: "@analogjs/vite-plugin-angular:encapsulation",
|
|
27
|
+
enforce: "post",
|
|
28
|
+
transform(code, id) {
|
|
29
|
+
if (shouldExternalizeStyles() && isComponentStyleSheet(id)) {
|
|
30
|
+
const { encapsulation, componentId } = getComponentStyleSheetMeta(id);
|
|
31
|
+
if (encapsulation === "emulated" && componentId) {
|
|
32
|
+
debugStylesV("applying emulated view encapsulation (post)", {
|
|
33
|
+
stylesheet: id.split("?")[0],
|
|
34
|
+
componentId
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
code: ngCompiler.encapsulateStyle(code, componentId),
|
|
38
|
+
map: null
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { encapsulationPlugin, getComponentStyleSheetMeta, isComponentStyleSheet };
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=encapsulation-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encapsulation-plugin.js","names":[],"sources":["../../../src/lib/encapsulation-plugin.ts"],"sourcesContent":["import * as ngCompiler from '@angular/compiler';\nimport { Plugin } from 'vite';\nimport { debugStylesV } from './utils/debug.js';\n\nexport function isComponentStyleSheet(id: string): boolean {\n return id.includes('ngcomp=');\n}\n\nexport function getComponentStyleSheetMeta(id: string): {\n componentId: string;\n encapsulation: 'emulated' | 'shadow' | 'none';\n} {\n const params = new URL(id, 'http://localhost').searchParams;\n const encapsulationMapping = {\n '0': 'emulated',\n '2': 'none',\n '3': 'shadow',\n };\n return {\n componentId: params.get('ngcomp')!,\n encapsulation: encapsulationMapping[\n params.get('e') as keyof typeof encapsulationMapping\n ] as 'emulated' | 'shadow' | 'none',\n };\n}\n\n/**\n * Encapsulation runs in enforce: 'post' so that @tailwindcss/vite\n * (enforce: 'pre') fully resolves @apply directives — including those\n * inside :host {} — before Angular's ShadowCss rewrites selectors.\n * (#2293)\n */\nexport function encapsulationPlugin(\n shouldExternalizeStyles: () => boolean,\n): Plugin {\n return {\n name: '@analogjs/vite-plugin-angular:encapsulation',\n enforce: 'post',\n transform(code: string, id: string) {\n if (shouldExternalizeStyles() && isComponentStyleSheet(id)) {\n const { encapsulation, componentId } = getComponentStyleSheetMeta(id);\n if (encapsulation === 'emulated' && componentId) {\n debugStylesV('applying emulated view encapsulation (post)', {\n stylesheet: id.split('?')[0],\n componentId,\n });\n const encapsulated = ngCompiler.encapsulateStyle(code, componentId);\n return {\n code: encapsulated,\n map: null,\n };\n }\n }\n },\n };\n}\n"],"mappings":";;;AAIA,SAAgB,sBAAsB,IAAqB;AACzD,QAAO,GAAG,SAAS,UAAU;;AAG/B,SAAgB,2BAA2B,IAGzC;CACA,MAAM,SAAS,IAAI,IAAI,IAAI,mBAAmB,CAAC;AAM/C,QAAO;EACL,aAAa,OAAO,IAAI,SAAS;EACjC,eAP2B;GAC3B,KAAK;GACL,KAAK;GACL,KAAK;GACN,CAIG,OAAO,IAAI,IAAI;EAElB;;;;;;;;AASH,SAAgB,oBACd,yBACQ;AACR,QAAO;EACL,MAAM;EACN,SAAS;EACT,UAAU,MAAc,IAAY;AAClC,OAAI,yBAAyB,IAAI,sBAAsB,GAAG,EAAE;IAC1D,MAAM,EAAE,eAAe,gBAAgB,2BAA2B,GAAG;AACrE,QAAI,kBAAkB,cAAc,aAAa;AAC/C,kBAAa,+CAA+C;MAC1D,YAAY,GAAG,MAAM,IAAI,CAAC;MAC1B;MACD,CAAC;AAEF,YAAO;MACL,MAFmB,WAAW,iBAAiB,MAAM,YAAY;MAGjE,KAAK;MACN;;;;EAIR"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
import { type ComponentRegistry } from "./compiler/index.js";
|
|
3
|
+
declare global {
|
|
4
|
+
/**
|
|
5
|
+
* Shared convention for out-of-tree compilers (e.g. `@tsrx/analog`) that
|
|
6
|
+
* produce Angular Ivy definitions from a non-TS source format. Populate
|
|
7
|
+
* this map with directive/component metadata for any class fastCompile
|
|
8
|
+
* can't reach through its own tsconfig-driven scan, and the per-compile
|
|
9
|
+
* registry lookup in `fastCompilePlugin` will merge those entries in —
|
|
10
|
+
* so TS `@Component({ imports: [X] })` references to such classes
|
|
11
|
+
* resolve statically instead of hitting the `_unresolved-${className}`
|
|
12
|
+
* sentinel.
|
|
13
|
+
*/
|
|
14
|
+
var __ANALOG_EXTERNAL_REGISTRY__: ComponentRegistry | undefined;
|
|
15
|
+
}
|
|
16
|
+
export interface FastCompilePluginOptions {
|
|
17
|
+
tsconfigGetter: () => string;
|
|
18
|
+
workspaceRoot: string;
|
|
19
|
+
inlineStylesExtension: string;
|
|
20
|
+
jit: boolean;
|
|
21
|
+
liveReload: boolean;
|
|
22
|
+
supportedBrowsers: string[];
|
|
23
|
+
transformFilter?: (code: string, id: string) => boolean;
|
|
24
|
+
isTest: boolean;
|
|
25
|
+
isAstroIntegration: boolean;
|
|
26
|
+
fastCompileMode?: "full" | "partial";
|
|
27
|
+
}
|
|
28
|
+
export declare function fastCompilePlugin(pluginOptions: FastCompilePluginOptions): Plugin;
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { TS_EXT_REGEX, createDepOptimizerConfig, getTsConfigPath, isProdMode } from "./utils/plugin-config.js";
|
|
2
|
+
import { toVirtualRawId } from "./utils/virtual-ids.js";
|
|
3
|
+
import { loadVirtualRawModule, rewriteHtmlRawImport } from "./utils/virtual-resources.js";
|
|
4
|
+
import { ANGULAR_DECORATOR_CALL_RE } from "./compiler/constants.js";
|
|
5
|
+
import { debugCompile, debugRegistry } from "./compiler/debug.js";
|
|
6
|
+
import { compile } from "./compiler/compile.js";
|
|
7
|
+
import { scanFile } from "./compiler/registry.js";
|
|
8
|
+
import { collectAllImports, collectImportedPackages, collectRelativeReExports, scanPackageDts } from "./compiler/dts-reader.js";
|
|
9
|
+
import { jitTransform } from "./compiler/jit-transform.js";
|
|
10
|
+
import { generateHmrCode } from "./compiler/hmr.js";
|
|
11
|
+
import { extractInlineStyles, inlineResourceUrls } from "./compiler/resource-inliner.js";
|
|
12
|
+
import "./compiler/index.js";
|
|
13
|
+
import { markStylePathSafe } from "./utils/safe-module-paths.js";
|
|
14
|
+
import { promises } from "node:fs";
|
|
15
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
16
|
+
import * as compilerCli from "@angular/compiler-cli";
|
|
17
|
+
import * as vite from "vite";
|
|
18
|
+
import { normalizePath, preprocessCSS } from "vite";
|
|
19
|
+
import { parseSync } from "oxc-parser";
|
|
20
|
+
//#region packages/vite-plugin-angular/src/lib/fast-compile-plugin.ts
|
|
21
|
+
function fastCompilePlugin(pluginOptions) {
|
|
22
|
+
let resolvedConfig;
|
|
23
|
+
let tsConfigResolutionContext = null;
|
|
24
|
+
let watchMode = false;
|
|
25
|
+
const registry = /* @__PURE__ */ new Map();
|
|
26
|
+
const resourceToSource = /* @__PURE__ */ new Map();
|
|
27
|
+
const scannedDtsPackages = /* @__PURE__ */ new Set();
|
|
28
|
+
let projectRoot = "";
|
|
29
|
+
let useDefineForClassFields = true;
|
|
30
|
+
/**
|
|
31
|
+
* Scan a file into the registry, then recursively walk its relative
|
|
32
|
+
* `export *` / `export { … } from './x'` chain so any underlying
|
|
33
|
+
* directive classes also land in the registry. Used both at
|
|
34
|
+
* `buildStart` (for tsconfig path entries) and at dev time (file
|
|
35
|
+
* `add` and `handleHotUpdate`) so newly added barrels stay in sync
|
|
36
|
+
* without requiring a server restart.
|
|
37
|
+
*
|
|
38
|
+
* The `visited` set prevents infinite recursion within a single
|
|
39
|
+
* top-level call. Each fresh scan should pass an empty set (so HMR
|
|
40
|
+
* re-scans aren't blocked by buildStart's earlier visits).
|
|
41
|
+
*
|
|
42
|
+
* `fileContents`/`scanResults` are cold-start dedup caches scoped to a
|
|
43
|
+
* single `initFastCompile` call. HMR/watcher callers must omit them so
|
|
44
|
+
* an edited file is always re-read from disk.
|
|
45
|
+
*/
|
|
46
|
+
async function scanBarrelExports(file, visited = /* @__PURE__ */ new Set(), overwrite = false, fileContents, scanResults) {
|
|
47
|
+
if (visited.has(file)) return;
|
|
48
|
+
visited.add(file);
|
|
49
|
+
let code;
|
|
50
|
+
try {
|
|
51
|
+
code = fileContents?.get(file) ?? await promises.readFile(file, "utf-8");
|
|
52
|
+
fileContents?.set(file, code);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
if (debugRegistry.enabled) debugRegistry("scanBarrelExports: failed to read %s: %s", file, e?.message);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
let program;
|
|
58
|
+
try {
|
|
59
|
+
program = parseSync(file, code).program;
|
|
60
|
+
} catch {
|
|
61
|
+
program = void 0;
|
|
62
|
+
}
|
|
63
|
+
let entries = scanResults?.get(file);
|
|
64
|
+
if (!entries) {
|
|
65
|
+
entries = scanFile(code, file, program);
|
|
66
|
+
scanResults?.set(file, entries);
|
|
67
|
+
}
|
|
68
|
+
for (const entry of entries) if (overwrite || !registry.has(entry.className)) registry.set(entry.className, entry);
|
|
69
|
+
const dir = dirname(file);
|
|
70
|
+
for (const rel of collectRelativeReExports(code, file, program)) {
|
|
71
|
+
const normalizedRel = rel.replace(/\.(?:js|mjs)$/u, "");
|
|
72
|
+
const reExportCandidates = [resolve(dir, normalizedRel + ".ts"), resolve(dir, normalizedRel, "index.ts")];
|
|
73
|
+
let resolved = false;
|
|
74
|
+
for (const candidate of reExportCandidates) try {
|
|
75
|
+
await promises.access(candidate);
|
|
76
|
+
await scanBarrelExports(candidate, visited, overwrite, fileContents, scanResults);
|
|
77
|
+
resolved = true;
|
|
78
|
+
break;
|
|
79
|
+
} catch {}
|
|
80
|
+
if (!resolved && debugRegistry.enabled) debugRegistry("scanBarrelExports: %s re-export %s did not resolve to %o", file, rel, reExportCandidates);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function initFastCompile() {
|
|
84
|
+
if (pluginOptions.jit) return;
|
|
85
|
+
registry.clear();
|
|
86
|
+
scannedDtsPackages.clear();
|
|
87
|
+
const resolvedTsConfigPath = resolveTsConfigPath();
|
|
88
|
+
projectRoot = dirname(resolvedTsConfigPath);
|
|
89
|
+
const config = compilerCli.readConfiguration(resolvedTsConfigPath);
|
|
90
|
+
useDefineForClassFields = config.options?.useDefineForClassFields ?? true;
|
|
91
|
+
const candidates = new Set(config.rootNames);
|
|
92
|
+
const tsPaths = config.options?.paths;
|
|
93
|
+
const baseUrl = config.options?.baseUrl ?? projectRoot;
|
|
94
|
+
const fileContents = /* @__PURE__ */ new Map();
|
|
95
|
+
const scanResults = /* @__PURE__ */ new Map();
|
|
96
|
+
if (tsPaths) for (const targets of Object.values(tsPaths)) for (const target of targets) {
|
|
97
|
+
if (target.includes("*")) continue;
|
|
98
|
+
candidates.add(resolve(baseUrl, target));
|
|
99
|
+
}
|
|
100
|
+
const results = await Promise.all(Array.from(candidates).map(async (file) => {
|
|
101
|
+
try {
|
|
102
|
+
const code = await promises.readFile(file, "utf-8");
|
|
103
|
+
fileContents.set(file, code);
|
|
104
|
+
const entries = scanFile(code, file);
|
|
105
|
+
scanResults.set(file, entries);
|
|
106
|
+
return entries;
|
|
107
|
+
} catch (e) {
|
|
108
|
+
if (debugRegistry.enabled) debugRegistry("initFastCompile: skipping unreadable %s: %s", file, e?.message);
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
}));
|
|
112
|
+
for (const entries of results) for (const entry of entries) registry.set(entry.className, entry);
|
|
113
|
+
const resolvePathSpecifier = (spec) => {
|
|
114
|
+
if (!tsPaths) return [];
|
|
115
|
+
for (const [key, targets] of Object.entries(tsPaths)) {
|
|
116
|
+
const list = targets;
|
|
117
|
+
if (key.endsWith("/*")) {
|
|
118
|
+
const prefix = key.slice(0, -1);
|
|
119
|
+
if (spec.startsWith(prefix)) return list.map((t) => resolve(baseUrl, t.split("*").join(spec.slice(prefix.length))));
|
|
120
|
+
} else if (key === spec) return list.map((t) => resolve(baseUrl, t));
|
|
121
|
+
}
|
|
122
|
+
return [];
|
|
123
|
+
};
|
|
124
|
+
const probeToSource = async (base) => {
|
|
125
|
+
const candidates = base.endsWith(".ts") ? [base] : [base + ".ts", resolve(base, "index.ts")];
|
|
126
|
+
for (const candidate of candidates) try {
|
|
127
|
+
await promises.access(candidate);
|
|
128
|
+
return candidate;
|
|
129
|
+
} catch {}
|
|
130
|
+
return null;
|
|
131
|
+
};
|
|
132
|
+
const baseResolveCache = /* @__PURE__ */ new Map();
|
|
133
|
+
const resolveToSource = (base) => {
|
|
134
|
+
let probe = baseResolveCache.get(base);
|
|
135
|
+
if (!probe) {
|
|
136
|
+
probe = probeToSource(base);
|
|
137
|
+
baseResolveCache.set(base, probe);
|
|
138
|
+
}
|
|
139
|
+
return probe;
|
|
140
|
+
};
|
|
141
|
+
const resolveFirstSource = async (bases) => {
|
|
142
|
+
for (const base of bases) {
|
|
143
|
+
const resolved = await resolveToSource(base);
|
|
144
|
+
if (resolved) return resolved;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
};
|
|
148
|
+
const importWalkVisited = /* @__PURE__ */ new Set();
|
|
149
|
+
const bareSpecResolveCache = /* @__PURE__ */ new Map();
|
|
150
|
+
const walkImports = async (file) => {
|
|
151
|
+
if (importWalkVisited.has(file)) return;
|
|
152
|
+
importWalkVisited.add(file);
|
|
153
|
+
let code;
|
|
154
|
+
try {
|
|
155
|
+
code = fileContents.get(file) ?? await promises.readFile(file, "utf-8");
|
|
156
|
+
fileContents.set(file, code);
|
|
157
|
+
} catch {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
let program;
|
|
161
|
+
try {
|
|
162
|
+
program = parseSync(file, code).program;
|
|
163
|
+
} catch {
|
|
164
|
+
program = void 0;
|
|
165
|
+
}
|
|
166
|
+
let entries = scanResults.get(file);
|
|
167
|
+
if (!entries) {
|
|
168
|
+
entries = scanFile(code, file, program);
|
|
169
|
+
scanResults.set(file, entries);
|
|
170
|
+
}
|
|
171
|
+
for (const entry of entries) if (!registry.has(entry.className)) registry.set(entry.className, entry);
|
|
172
|
+
for (const pkg of collectImportedPackages(code, file, program)) {
|
|
173
|
+
if (scannedDtsPackages.has(pkg)) continue;
|
|
174
|
+
scannedDtsPackages.add(pkg);
|
|
175
|
+
try {
|
|
176
|
+
for (const entry of scanPackageDts(pkg, projectRoot, scannedDtsPackages)) if (!registry.has(entry.className)) registry.set(entry.className, entry);
|
|
177
|
+
} catch {}
|
|
178
|
+
}
|
|
179
|
+
const dir = dirname(file);
|
|
180
|
+
const targets = await Promise.all(collectAllImports(code, file, program).map((spec) => {
|
|
181
|
+
if (spec.startsWith(".")) return resolveToSource(resolve(dir, spec.replace(/\.(?:js|mjs)$/u, "")));
|
|
182
|
+
let resolved = bareSpecResolveCache.get(spec);
|
|
183
|
+
if (!resolved) {
|
|
184
|
+
resolved = resolveFirstSource(resolvePathSpecifier(spec));
|
|
185
|
+
bareSpecResolveCache.set(spec, resolved);
|
|
186
|
+
}
|
|
187
|
+
return resolved;
|
|
188
|
+
}));
|
|
189
|
+
await Promise.all(targets.filter((t) => !!t).map((t) => walkImports(t)));
|
|
190
|
+
};
|
|
191
|
+
await Promise.all(config.rootNames.map((file) => walkImports(file)));
|
|
192
|
+
const buildStartVisited = /* @__PURE__ */ new Set();
|
|
193
|
+
if (tsPaths) {
|
|
194
|
+
const barrelCandidates = [];
|
|
195
|
+
for (const targets of Object.values(tsPaths)) for (const target of targets) {
|
|
196
|
+
if (target.includes("*")) continue;
|
|
197
|
+
barrelCandidates.push(resolve(baseUrl, target));
|
|
198
|
+
}
|
|
199
|
+
await Promise.all(barrelCandidates.map((c) => scanBarrelExports(c, buildStartVisited, false, fileContents, scanResults)));
|
|
200
|
+
}
|
|
201
|
+
debugRegistry("initFastCompile done: %d entries from %d candidate files", registry.size, candidates.size);
|
|
202
|
+
}
|
|
203
|
+
function ensureDtsRegistryForSource(code, id, program) {
|
|
204
|
+
for (const pkg of collectImportedPackages(code, id, program)) {
|
|
205
|
+
if (scannedDtsPackages.has(pkg)) continue;
|
|
206
|
+
scannedDtsPackages.add(pkg);
|
|
207
|
+
try {
|
|
208
|
+
const dtsEntries = scanPackageDts(pkg, projectRoot, scannedDtsPackages);
|
|
209
|
+
for (const entry of dtsEntries) if (!registry.has(entry.className)) registry.set(entry.className, entry);
|
|
210
|
+
} catch {}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
async function handleFastCompileTransform(code, id) {
|
|
214
|
+
if (!ANGULAR_DECORATOR_CALL_RE.test(code)) {
|
|
215
|
+
const stripped = vite.transformWithOxc ? await vite.transformWithOxc(code, id, {
|
|
216
|
+
lang: "ts",
|
|
217
|
+
sourcemap: true,
|
|
218
|
+
decorator: {
|
|
219
|
+
legacy: false,
|
|
220
|
+
emitDecoratorMetadata: false
|
|
221
|
+
}
|
|
222
|
+
}) : await vite.transformWithEsbuild(code, id, {
|
|
223
|
+
loader: "ts",
|
|
224
|
+
sourcemap: true
|
|
225
|
+
});
|
|
226
|
+
return {
|
|
227
|
+
code: stripped.code,
|
|
228
|
+
map: stripped.map
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
if (pluginOptions.jit) {
|
|
232
|
+
const result = jitTransform(code, id);
|
|
233
|
+
const inMap = result.map ?? void 0;
|
|
234
|
+
const stripped = vite.transformWithOxc ? await vite.transformWithOxc(result.code, id, {
|
|
235
|
+
lang: "ts",
|
|
236
|
+
sourcemap: true,
|
|
237
|
+
decorator: {
|
|
238
|
+
legacy: false,
|
|
239
|
+
emitDecoratorMetadata: false
|
|
240
|
+
}
|
|
241
|
+
}, inMap) : await vite.transformWithEsbuild(result.code, id, {
|
|
242
|
+
loader: "ts",
|
|
243
|
+
sourcemap: true
|
|
244
|
+
}, inMap);
|
|
245
|
+
return {
|
|
246
|
+
code: stripped.code,
|
|
247
|
+
map: stripped.map
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
const inlined = await inlineResourceUrls(code, id);
|
|
251
|
+
code = inlined.code;
|
|
252
|
+
const { styleExtensions } = inlined;
|
|
253
|
+
for (const dep of inlined.resourceDependencies) resourceToSource.set(dep, id);
|
|
254
|
+
const { program: oxcProgram } = parseSync(id, code);
|
|
255
|
+
let resolvedStyles;
|
|
256
|
+
let resolvedInlineStyles;
|
|
257
|
+
const inlineExt = pluginOptions.inlineStylesExtension;
|
|
258
|
+
const styleNeedsPreprocess = (ext) => ext !== "" && ext !== "css";
|
|
259
|
+
if (styleNeedsPreprocess(inlineExt) || styleExtensions.size > 0) {
|
|
260
|
+
const styleStrings = extractInlineStyles(code, id, oxcProgram);
|
|
261
|
+
if (styleStrings.length > 0) {
|
|
262
|
+
resolvedInlineStyles = /* @__PURE__ */ new Map();
|
|
263
|
+
for (let i = 0; i < styleStrings.length; i++) {
|
|
264
|
+
const ext = styleExtensions.get(i) ?? inlineExt;
|
|
265
|
+
if (!styleNeedsPreprocess(ext)) continue;
|
|
266
|
+
try {
|
|
267
|
+
const fakePath = id.replace(/\.ts$/, `.inline-${i}.${ext}`);
|
|
268
|
+
const processed = await preprocessCSS(styleStrings[i], fakePath, resolvedConfig);
|
|
269
|
+
resolvedInlineStyles.set(i, processed.code);
|
|
270
|
+
} catch (e) {
|
|
271
|
+
if (debugCompile.enabled) debugCompile("inline style #%d preprocessing failed in %s: %s", i, id, e?.message);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (resolvedInlineStyles.size === 0) resolvedInlineStyles = void 0;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
ensureDtsRegistryForSource(code, id, oxcProgram);
|
|
278
|
+
let compileRegistry = registry;
|
|
279
|
+
const externalRegistry = globalThis.__ANALOG_EXTERNAL_REGISTRY__;
|
|
280
|
+
if (externalRegistry && externalRegistry.size > 0) {
|
|
281
|
+
compileRegistry = new Map(registry);
|
|
282
|
+
for (const [k, v] of externalRegistry) compileRegistry.set(k, v);
|
|
283
|
+
}
|
|
284
|
+
const result = compile(code, id, {
|
|
285
|
+
registry: compileRegistry,
|
|
286
|
+
resolvedStyles,
|
|
287
|
+
resolvedInlineStyles,
|
|
288
|
+
useDefineForClassFields,
|
|
289
|
+
compilationMode: pluginOptions.fastCompileMode,
|
|
290
|
+
oxcProgram
|
|
291
|
+
});
|
|
292
|
+
for (const dep of result.resourceDependencies) resourceToSource.set(dep, id);
|
|
293
|
+
let outputCode = (vite.transformWithOxc ? await vite.transformWithOxc(result.code, id, {
|
|
294
|
+
lang: "ts",
|
|
295
|
+
sourcemap: false,
|
|
296
|
+
decorator: {
|
|
297
|
+
legacy: false,
|
|
298
|
+
emitDecoratorMetadata: false
|
|
299
|
+
}
|
|
300
|
+
}) : await vite.transformWithEsbuild(result.code, id, {
|
|
301
|
+
loader: "ts",
|
|
302
|
+
sourcemap: false
|
|
303
|
+
})).code;
|
|
304
|
+
if (watchMode && pluginOptions.liveReload) {
|
|
305
|
+
const fileDeclarations = [...registry.values()].filter((e) => e.fileName === id);
|
|
306
|
+
if (fileDeclarations.length > 0) {
|
|
307
|
+
const localDepClassNames = fileDeclarations.map((e) => e.className);
|
|
308
|
+
outputCode += generateHmrCode(fileDeclarations, localDepClassNames);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
code: outputCode,
|
|
313
|
+
map: result.map
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function resolveTsConfigPath() {
|
|
317
|
+
const { root, isProd, isLib } = tsConfigResolutionContext;
|
|
318
|
+
return getTsConfigPath(root, pluginOptions.tsconfigGetter(), isProd, pluginOptions.isTest, isLib, pluginOptions.workspaceRoot);
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
name: "@analogjs/vite-plugin-angular-fast-compile",
|
|
322
|
+
enforce: "pre",
|
|
323
|
+
async config(config, { command }) {
|
|
324
|
+
watchMode = command === "serve";
|
|
325
|
+
const isProd = isProdMode(config.mode);
|
|
326
|
+
tsConfigResolutionContext = {
|
|
327
|
+
root: config.root || ".",
|
|
328
|
+
isProd,
|
|
329
|
+
isLib: !!config?.build?.lib
|
|
330
|
+
};
|
|
331
|
+
const depOptimizer = createDepOptimizerConfig({
|
|
332
|
+
tsconfig: resolveTsConfigPath(),
|
|
333
|
+
isProd,
|
|
334
|
+
jit: pluginOptions.jit,
|
|
335
|
+
watchMode,
|
|
336
|
+
isTest: pluginOptions.isTest,
|
|
337
|
+
isAstroIntegration: pluginOptions.isAstroIntegration
|
|
338
|
+
});
|
|
339
|
+
return {
|
|
340
|
+
...vite.rolldownVersion ? { oxc: {} } : { esbuild: false },
|
|
341
|
+
...depOptimizer
|
|
342
|
+
};
|
|
343
|
+
},
|
|
344
|
+
configResolved(config) {
|
|
345
|
+
resolvedConfig = config;
|
|
346
|
+
},
|
|
347
|
+
configureServer(server) {
|
|
348
|
+
server.watcher.on("add", async (filePath) => {
|
|
349
|
+
if (filePath.endsWith(".ts") && !filePath.endsWith(".spec.ts") && !filePath.endsWith(".d.ts")) await scanBarrelExports(filePath, /* @__PURE__ */ new Set(), true);
|
|
350
|
+
});
|
|
351
|
+
},
|
|
352
|
+
async buildStart() {
|
|
353
|
+
await initFastCompile();
|
|
354
|
+
},
|
|
355
|
+
async handleHotUpdate(ctx) {
|
|
356
|
+
if (resourceToSource.has(ctx.file)) {
|
|
357
|
+
const parentSource = resourceToSource.get(ctx.file);
|
|
358
|
+
const parentModule = ctx.server.moduleGraph.getModuleById(parentSource);
|
|
359
|
+
if (parentModule) return [parentModule];
|
|
360
|
+
}
|
|
361
|
+
if (TS_EXT_REGEX.test(ctx.file)) {
|
|
362
|
+
const [fileId] = ctx.file.split("?");
|
|
363
|
+
const oldEntries = [...registry.entries()].filter(([_, v]) => v.fileName === fileId).map(([k]) => k);
|
|
364
|
+
for (const key of oldEntries) registry.delete(key);
|
|
365
|
+
await scanBarrelExports(fileId, /* @__PURE__ */ new Set(), true);
|
|
366
|
+
}
|
|
367
|
+
return ctx.modules;
|
|
368
|
+
},
|
|
369
|
+
resolveId(id, importer) {
|
|
370
|
+
if (id.startsWith("virtual:@analogjs/vite-plugin-angular:raw:")) return `\0${id}`;
|
|
371
|
+
if (pluginOptions.jit && id.startsWith("angular:jit:")) {
|
|
372
|
+
const filePath = normalizePath(resolve(dirname(importer), id.split(";")[1]));
|
|
373
|
+
if (id.includes(":style")) {
|
|
374
|
+
markStylePathSafe(resolvedConfig, filePath);
|
|
375
|
+
return filePath + "?inline";
|
|
376
|
+
}
|
|
377
|
+
return toVirtualRawId(filePath);
|
|
378
|
+
}
|
|
379
|
+
const rawRewrite = rewriteHtmlRawImport(id, importer);
|
|
380
|
+
if (rawRewrite) return rawRewrite;
|
|
381
|
+
if (/\.(css|scss|sass|less)\?inline$/.test(id) && importer) {
|
|
382
|
+
const filePath = id.split("?")[0];
|
|
383
|
+
const resolved = isAbsolute(filePath) ? normalizePath(filePath) : normalizePath(resolve(dirname(importer), filePath));
|
|
384
|
+
markStylePathSafe(resolvedConfig, resolved);
|
|
385
|
+
return resolved + "?inline";
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
async load(id) {
|
|
389
|
+
const rawModule = await loadVirtualRawModule(this, id);
|
|
390
|
+
if (rawModule !== void 0) return rawModule;
|
|
391
|
+
if (/\.(css|scss|sass|less)\?inline$/.test(id)) markStylePathSafe(resolvedConfig, id.split("?")[0]);
|
|
392
|
+
},
|
|
393
|
+
transform: {
|
|
394
|
+
filter: { id: {
|
|
395
|
+
include: [TS_EXT_REGEX],
|
|
396
|
+
exclude: [
|
|
397
|
+
/node_modules/,
|
|
398
|
+
"type=script",
|
|
399
|
+
"@ng/component",
|
|
400
|
+
/[?&]raw\b/
|
|
401
|
+
]
|
|
402
|
+
} },
|
|
403
|
+
async handler(code, id) {
|
|
404
|
+
if (pluginOptions.transformFilter && !(pluginOptions.transformFilter(code, id) ?? true)) return;
|
|
405
|
+
if (id.includes(".ts?")) id = id.replace(/\?(.*)/, "");
|
|
406
|
+
return handleFastCompileTransform(code, id);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
//#endregion
|
|
412
|
+
export { fastCompilePlugin };
|
|
413
|
+
|
|
414
|
+
//# sourceMappingURL=fast-compile-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fast-compile-plugin.js","names":[],"sources":["../../../src/lib/fast-compile-plugin.ts"],"sourcesContent":["import { promises as fsPromises } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { parseSync } from 'oxc-parser';\nimport * as vite from 'vite';\n\nimport * as compilerCli from '@angular/compiler-cli';\nimport { normalizePath, Plugin, preprocessCSS, ResolvedConfig } from 'vite';\n\nimport {\n compile,\n scanFile,\n scanPackageDts,\n collectImportedPackages,\n collectRelativeReExports,\n collectAllImports,\n jitTransform,\n inlineResourceUrls,\n extractInlineStyles,\n generateHmrCode,\n debugCompile,\n debugRegistry,\n ANGULAR_DECORATOR_CALL_RE,\n type ComponentRegistry,\n} from './compiler/index.js';\n\nimport {\n TS_EXT_REGEX,\n getTsConfigPath,\n createDepOptimizerConfig,\n isProdMode,\n type TsConfigResolutionContext,\n} from './utils/plugin-config.js';\nimport { VIRTUAL_RAW_PREFIX, toVirtualRawId } from './utils/virtual-ids.js';\nimport {\n loadVirtualRawModule,\n rewriteHtmlRawImport,\n} from './utils/virtual-resources.js';\nimport { markStylePathSafe } from './utils/safe-module-paths.js';\n\ndeclare global {\n /**\n * Shared convention for out-of-tree compilers (e.g. `@tsrx/analog`) that\n * produce Angular Ivy definitions from a non-TS source format. Populate\n * this map with directive/component metadata for any class fastCompile\n * can't reach through its own tsconfig-driven scan, and the per-compile\n * registry lookup in `fastCompilePlugin` will merge those entries in —\n * so TS `@Component({ imports: [X] })` references to such classes\n * resolve statically instead of hitting the `_unresolved-${className}`\n * sentinel.\n */\n // eslint-disable-next-line no-var\n var __ANALOG_EXTERNAL_REGISTRY__: ComponentRegistry | undefined;\n}\n\nexport interface FastCompilePluginOptions {\n tsconfigGetter: () => string;\n workspaceRoot: string;\n inlineStylesExtension: string;\n jit: boolean;\n liveReload: boolean;\n supportedBrowsers: string[];\n transformFilter?: (code: string, id: string) => boolean;\n isTest: boolean;\n isAstroIntegration: boolean;\n fastCompileMode?: 'full' | 'partial';\n}\n\nexport function fastCompilePlugin(\n pluginOptions: FastCompilePluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n let tsConfigResolutionContext: TsConfigResolutionContext | null = null;\n let watchMode = false;\n\n // fast-compile plugin state\n const registry: ComponentRegistry = new Map();\n const resourceToSource = new Map<string, string>();\n const scannedDtsPackages = new Set<string>();\n let projectRoot = '';\n let useDefineForClassFields = true;\n\n /**\n * Scan a file into the registry, then recursively walk its relative\n * `export *` / `export { … } from './x'` chain so any underlying\n * directive classes also land in the registry. Used both at\n * `buildStart` (for tsconfig path entries) and at dev time (file\n * `add` and `handleHotUpdate`) so newly added barrels stay in sync\n * without requiring a server restart.\n *\n * The `visited` set prevents infinite recursion within a single\n * top-level call. Each fresh scan should pass an empty set (so HMR\n * re-scans aren't blocked by buildStart's earlier visits).\n *\n * `fileContents`/`scanResults` are cold-start dedup caches scoped to a\n * single `initFastCompile` call. HMR/watcher callers must omit them so\n * an edited file is always re-read from disk.\n */\n async function scanBarrelExports(\n file: string,\n visited: Set<string> = new Set(),\n overwrite = false,\n fileContents?: Map<string, string>,\n scanResults?: Map<string, ReturnType<typeof scanFile>>,\n ): Promise<void> {\n if (visited.has(file)) return;\n visited.add(file);\n let code: string;\n try {\n code =\n fileContents?.get(file) ?? (await fsPromises.readFile(file, 'utf-8'));\n fileContents?.set(file, code);\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: failed to read %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return;\n }\n // Single parse shared by scanFile and collectRelativeReExports. On a\n // parse error each consumer re-parses on its own, preserving their\n // individual failure semantics (scanFile throws past its pre-filter;\n // collectRelativeReExports swallows and returns []).\n let program: ReturnType<typeof parseSync>['program'] | undefined;\n try {\n program = parseSync(file, code).program;\n } catch {\n program = undefined;\n }\n let entries = scanResults?.get(file);\n if (!entries) {\n entries = scanFile(code, file, program);\n scanResults?.set(file, entries);\n }\n for (const entry of entries) {\n // At buildStart we want stable registry entries (don't overwrite\n // an earlier scan with a barrel re-scan); HMR explicitly asks\n // for overwrite so updated metadata replaces stale entries.\n if (overwrite || !registry.has(entry.className)) {\n registry.set(entry.className, entry);\n }\n }\n // Collect every relative re-export specifier via OXC AST so\n // recursive scans can't trip over each other (a shared `/g` regex\n // would have its `lastIndex` reset by each recursive call and\n // silently skip half of an outer barrel's re-exports, which\n // previously left directives like `HlmRadioGroup` unregistered).\n const dir = dirname(file);\n for (const rel of collectRelativeReExports(code, file, program)) {\n // NodeNext-style libraries write `export * from './foo.js'`\n // even though the source is `./foo.ts`. Strip the ESM\n // extension before probing or the candidates would be\n // `foo.js.ts` / `foo.js/index.ts`, which never exist.\n const normalizedRel = rel.replace(/\\.(?:js|mjs)$/u, '');\n const reExportCandidates = [\n resolve(dir, normalizedRel + '.ts'),\n resolve(dir, normalizedRel, 'index.ts'),\n ];\n let resolved = false;\n for (const candidate of reExportCandidates) {\n try {\n await fsPromises.access(candidate);\n await scanBarrelExports(\n candidate,\n visited,\n overwrite,\n fileContents,\n scanResults,\n );\n resolved = true;\n break;\n } catch {\n // try next candidate\n }\n }\n if (!resolved && debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: %s re-export %s did not resolve to %o',\n file,\n rel,\n reExportCandidates,\n );\n }\n }\n }\n\n async function initFastCompile() {\n if (pluginOptions.jit) return; // JIT: no registry scan needed\n\n // Scan all source files to build the registry\n registry.clear();\n scannedDtsPackages.clear();\n const resolvedTsConfigPath = resolveTsConfigPath();\n projectRoot = dirname(resolvedTsConfigPath);\n const config = compilerCli.readConfiguration(resolvedTsConfigPath);\n useDefineForClassFields = config.options?.useDefineForClassFields ?? true;\n\n // Collect candidate files: tsconfig rootNames PLUS the entry points\n // named in `compilerOptions.paths`. App tsconfigs typically only\n // include the app's own sources, so workspace library entry barrels\n // (e.g. `HlmSelectImports = [HlmSelect, HlmSelectContent, ...] as\n // const`) live outside `rootNames` and would otherwise miss the\n // initial scan. The compiler then can't see that `HlmSelectImports`\n // is a tuple barrel and emits the bare identifier into the parent\n // component's `dependencies()` list, where Angular's runtime\n // silently drops it because arrays don't have a directive def.\n const candidates = new Set<string>(config.rootNames);\n const tsPaths = config.options?.paths;\n const baseUrl = (config.options?.baseUrl ?? projectRoot) as string;\n // Cold-start dedup caches shared by the three scan phases below\n // (candidates scan, walkImports, scanBarrelExports). Scoped to this\n // init call only — HMR/watcher re-scans must hit disk fresh.\n const fileContents = new Map<string, string>();\n const scanResults = new Map<string, ReturnType<typeof scanFile>>();\n if (tsPaths) {\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n // Skip wildcard patterns — entry barrels are normally exact\n // file paths like \"libs/helm/select/src/index.ts\".\n if (target.includes('*')) continue;\n candidates.add(resolve(baseUrl, target));\n }\n }\n }\n const results = await Promise.all(\n Array.from(candidates).map(async (file) => {\n try {\n const code = await fsPromises.readFile(file, 'utf-8');\n fileContents.set(file, code);\n const entries = scanFile(code, file);\n scanResults.set(file, entries);\n return entries;\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'initFastCompile: skipping unreadable %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return []; // Skip unreadable files\n }\n }),\n );\n\n for (const entries of results) {\n for (const entry of entries) {\n registry.set(entry.className, entry);\n }\n }\n\n // Walk the transitive import graph from the root files so the registry also\n // contains declarations that live in files not directly in tsconfig\n // `files`/`include` (transitively-imported app sources) and in workspace\n // libraries reached through wildcard `paths` (e.g. `@bitwarden/*`). Without\n // this, a non-standalone component's owning module can't classify its\n // declarations and `ɵɵsetComponentScope` is never emitted for it. Only\n // relative imports and `paths`-mapped (project/workspace) bare specifiers are\n // followed; true `node_modules` packages are left to the lazy `.d.ts` scanner.\n // Return *all* candidate base paths a bare specifier maps to. A `paths`\n // entry can list several fallback targets (e.g. a built `dist` path first\n // and the workspace `src` second); the caller probes them in order.\n const resolvePathSpecifier = (spec: string): string[] => {\n if (!tsPaths) return [];\n for (const [key, targets] of Object.entries(tsPaths)) {\n const list = targets as string[];\n if (key.endsWith('/*')) {\n const prefix = key.slice(0, -1);\n if (spec.startsWith(prefix)) {\n // `split('*').join(...)` substitutes the single tsconfig `*`\n // wildcard without `String.replace`'s first-match-only behavior or\n // `$`-pattern interpretation of the replacement.\n return list.map((t) =>\n resolve(baseUrl, t.split('*').join(spec.slice(prefix.length))),\n );\n }\n } else if (key === spec) {\n return list.map((t) => resolve(baseUrl, t));\n }\n }\n return [];\n };\n const probeToSource = async (base: string): Promise<string | null> => {\n const candidates = base.endsWith('.ts')\n ? [base]\n : [base + '.ts', resolve(base, 'index.ts')];\n for (const candidate of candidates) {\n try {\n await fsPromises.access(candidate);\n return candidate;\n } catch {\n // try next candidate\n }\n }\n return null;\n };\n // Memoize fs probes per absolute base path. The cache stores the\n // Promise (not the settled value) so concurrent walks racing on the\n // same base collapse into a single probe.\n const baseResolveCache = new Map<string, Promise<string | null>>();\n const resolveToSource = (base: string): Promise<string | null> => {\n let probe = baseResolveCache.get(base);\n if (!probe) {\n probe = probeToSource(base);\n baseResolveCache.set(base, probe);\n }\n return probe;\n };\n // Probe each `paths` target in order; first one that resolves to source wins.\n const resolveFirstSource = async (\n bases: string[],\n ): Promise<string | null> => {\n for (const base of bases) {\n const resolved = await resolveToSource(base);\n if (resolved) return resolved;\n }\n return null;\n };\n const importWalkVisited = new Set<string>();\n // Paths-mapped resolution doesn't depend on the importer, so bare\n // specifiers can be memoized by their raw text. Relative specifiers\n // must NOT be — the same './foo' resolves differently per directory.\n const bareSpecResolveCache = new Map<string, Promise<string | null>>();\n const walkImports = async (file: string): Promise<void> => {\n if (importWalkVisited.has(file)) return;\n importWalkVisited.add(file);\n let code: string;\n try {\n code =\n fileContents.get(file) ?? (await fsPromises.readFile(file, 'utf-8'));\n fileContents.set(file, code);\n } catch {\n return;\n }\n // Single parse shared by scanFile, collectImportedPackages, and\n // collectAllImports. On a parse error each consumer re-parses on\n // its own, preserving their individual failure semantics.\n let program: ReturnType<typeof parseSync>['program'] | undefined;\n try {\n program = parseSync(file, code).program;\n } catch {\n program = undefined;\n }\n let entries = scanResults.get(file);\n if (!entries) {\n entries = scanFile(code, file, program);\n scanResults.set(file, entries);\n }\n for (const entry of entries) {\n if (!registry.has(entry.className))\n registry.set(entry.className, entry);\n }\n // Pre-scan the `.d.ts` of every external package this file imports (and,\n // transitively, packages those packages' NgModules re-export — e.g.\n // BrowserModule → CommonModule → NgIf). Doing this at buildStart means the\n // registry is complete before any component transforms, so non-standalone\n // component scope resolves regardless of file transform order.\n for (const pkg of collectImportedPackages(code, file, program)) {\n if (scannedDtsPackages.has(pkg)) continue;\n scannedDtsPackages.add(pkg);\n try {\n for (const entry of scanPackageDts(\n pkg,\n projectRoot,\n scannedDtsPackages,\n )) {\n if (!registry.has(entry.className))\n registry.set(entry.className, entry);\n }\n } catch {\n // Package may not have .d.ts or not be Angular\n }\n }\n const dir = dirname(file);\n const targets = await Promise.all(\n collectAllImports(code, file, program).map((spec) => {\n if (spec.startsWith('.')) {\n return resolveToSource(\n resolve(dir, spec.replace(/\\.(?:js|mjs)$/u, '')),\n );\n }\n let resolved = bareSpecResolveCache.get(spec);\n if (!resolved) {\n resolved = resolveFirstSource(resolvePathSpecifier(spec));\n bareSpecResolveCache.set(spec, resolved);\n }\n return resolved;\n }),\n );\n await Promise.all(\n targets.filter((t): t is string => !!t).map((t) => walkImports(t)),\n );\n };\n await Promise.all(config.rootNames.map((file) => walkImports(file)));\n\n // Library barrels typically `export * from './lib/...'` rather than\n // declaring directives directly, so the entry file alone gives us\n // the tuple consts but not the directive classes they reference.\n // Walk the relative `export *` chain so the underlying classes also\n // land in the registry. Use a SHARED visited set across all\n // barrels so recursive walks don't double-scan a file that's\n // re-exported from multiple entry points.\n const buildStartVisited = new Set<string>();\n if (tsPaths) {\n const barrelCandidates: string[] = [];\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n if (target.includes('*')) continue;\n barrelCandidates.push(resolve(baseUrl, target));\n }\n }\n await Promise.all(\n barrelCandidates.map((c) =>\n scanBarrelExports(\n c,\n buildStartVisited,\n false,\n fileContents,\n scanResults,\n ),\n ),\n );\n }\n debugRegistry(\n 'initFastCompile done: %d entries from %d candidate files',\n registry.size,\n candidates.size,\n );\n }\n\n function ensureDtsRegistryForSource(\n code: string,\n id: string,\n program?: ReturnType<typeof parseSync>['program'],\n ) {\n for (const pkg of collectImportedPackages(code, id, program)) {\n if (scannedDtsPackages.has(pkg)) continue;\n scannedDtsPackages.add(pkg);\n\n try {\n const dtsEntries = scanPackageDts(pkg, projectRoot, scannedDtsPackages);\n for (const entry of dtsEntries) {\n if (!registry.has(entry.className)) {\n registry.set(entry.className, entry);\n }\n }\n } catch {\n // Package may not have .d.ts files or may not be Angular\n }\n }\n }\n\n async function handleFastCompileTransform(\n code: string,\n id: string,\n ): Promise<{ code: string; map: any } | undefined> {\n if (!ANGULAR_DECORATOR_CALL_RE.test(code)) {\n // Non-Angular file — strip TS-only syntax ourselves so barrels\n // like `export { Foo, type Bar } from './x'` and other TS-only\n // forms don't leak unstripped to Rolldown. In rolldown-vite the\n // built-in `vite:oxc` strip is registered as a Rust-side native\n // plugin (`viteTransformPlugin` from `rolldown/experimental`); if\n // its hook-filter treats files our `transform.filter.id.include`\n // claimed as already-handled, no JS-side fallback runs and raw\n // TS reaches the parser → `SyntaxError: Unexpected identifier`.\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(code, id, {\n lang: 'ts',\n sourcemap: true,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n })\n : await vite.transformWithEsbuild(code, id, {\n loader: 'ts',\n sourcemap: true,\n });\n return { code: stripped.code, map: stripped.map };\n }\n\n // JIT mode\n if (pluginOptions.jit) {\n const result = jitTransform(code, id);\n // Strip TypeScript-only syntax (e.g. `readonly`, parameter property\n // modifiers, type annotations on fields) so the output is valid JS\n // for Rolldown. `angularVitestSourcemapPlugin` normally runs this\n // strip downstream in tests, but it is intentionally skipped on\n // StackBlitz / WebContainer — and the production build pipeline\n // does not register it either — so the JIT path must self-strip\n // to stay safe across environments.\n //\n // Pass the jitTransform map as `inMap` so OXC/esbuild emit a map\n // composed with the original `.ts` source — without this, debug\n // stack traces and breakpoints land on the wrong lines once the\n // strip removes any TS-only token. `jitTransform` returns\n // `map: null` for files with no Angular class (no edits made);\n // passing that to OXC/esbuild as `inMap` throws, so coerce to\n // `undefined` in that case.\n const inMap = result.map ?? undefined;\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(\n result.code,\n id,\n {\n lang: 'ts',\n sourcemap: true,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n },\n inMap,\n )\n : await vite.transformWithEsbuild(\n result.code,\n id,\n { loader: 'ts', sourcemap: true },\n inMap,\n );\n return { code: stripped.code, map: stripped.map };\n }\n\n // Inline external templateUrl/styleUrl(s) into the source before compilation.\n // `styleExtensions` carries the source extension of each inlined external\n // style so it can be preprocessed by its own file type (e.g. an external\n // `.scss` styleUrl) regardless of the `inlineStylesExtension` option.\n const inlined = await inlineResourceUrls(code, id);\n code = inlined.code;\n const { styleExtensions } = inlined;\n\n // Track inlined resources for HMR. `compile()` only reports resources it\n // reads through its own fallback (a templateUrl/styleUrl the inliner did\n // NOT already inline), so files inlined here must be recorded here or a\n // later edit to them never invalidates the owning module.\n for (const dep of inlined.resourceDependencies) {\n resourceToSource.set(dep, id);\n }\n\n // Single OXC parse of the post-inline source, shared by every AST\n // consumer below. `inlineResourceUrls` parsed the PRE-inline string,\n // so its program can never be reused here.\n const { program: oxcProgram } = parseSync(id, code);\n\n // Pre-resolve inline styles that need preprocessing (SCSS/Sass/Less). Run\n // whenever a style needs a non-`css` preprocessor — either the configured\n // `inlineStylesExtension` for truly-inline styles, or an external styleUrl's\n // own extension.\n let resolvedStyles: Map<string, string> | undefined;\n let resolvedInlineStyles: Map<number, string> | undefined;\n\n const inlineExt = pluginOptions.inlineStylesExtension;\n const styleNeedsPreprocess = (ext: string) => ext !== '' && ext !== 'css';\n\n if (styleNeedsPreprocess(inlineExt) || styleExtensions.size > 0) {\n const styleStrings = extractInlineStyles(code, id, oxcProgram);\n\n if (styleStrings.length > 0) {\n resolvedInlineStyles = new Map();\n for (let i = 0; i < styleStrings.length; i++) {\n // External styleUrls are preprocessed by their own extension; truly\n // inline `styles: [...]` fall back to `inlineStylesExtension`.\n const ext = styleExtensions.get(i) ?? inlineExt;\n if (!styleNeedsPreprocess(ext)) continue;\n try {\n const fakePath = id.replace(/\\.ts$/, `.inline-${i}.${ext}`);\n const processed = await preprocessCSS(\n styleStrings[i],\n fakePath,\n resolvedConfig,\n );\n resolvedInlineStyles.set(i, processed.code);\n } catch (e) {\n if (debugCompile.enabled) {\n debugCompile(\n 'inline style #%d preprocessing failed in %s: %s',\n i,\n id,\n (e as Error)?.message,\n );\n }\n // Skip styles that can't be preprocessed\n }\n }\n if (resolvedInlineStyles.size === 0) resolvedInlineStyles = undefined;\n }\n }\n\n ensureDtsRegistryForSource(code, id, oxcProgram);\n\n // Merge entries from the shared external-registry global into this\n // compile's lookup view. Convention: out-of-tree compilers populate\n // `globalThis.__ANALOG_EXTERNAL_REGISTRY__` with directive metadata\n // for classes fastCompile can't reach through its tsconfig-driven\n // scan (e.g. `.tsrx` files compiled by `@tsrx/analog`). Without this\n // merge, a TS `@Component({ imports: [X] })` that references such a\n // class hits `_unresolved-${className}` as its selector and the tag\n // never matches at runtime.\n let compileRegistry: ComponentRegistry = registry;\n const externalRegistry = globalThis.__ANALOG_EXTERNAL_REGISTRY__;\n if (externalRegistry && externalRegistry.size > 0) {\n compileRegistry = new Map(registry);\n for (const [k, v] of externalRegistry) compileRegistry.set(k, v);\n }\n\n const result = compile(code, id, {\n registry: compileRegistry,\n resolvedStyles,\n resolvedInlineStyles,\n useDefineForClassFields,\n compilationMode: pluginOptions.fastCompileMode,\n oxcProgram,\n });\n\n // Track resource dependencies for HMR\n for (const dep of result.resourceDependencies) {\n resourceToSource.set(dep, id);\n }\n\n // Strip TypeScript-only syntax\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(result.code, id, {\n lang: 'ts',\n sourcemap: false,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n })\n : await vite.transformWithEsbuild(result.code, id, {\n loader: 'ts',\n sourcemap: false,\n });\n let outputCode = stripped.code;\n\n // Append HMR code in dev mode\n if (watchMode && pluginOptions.liveReload) {\n const fileDeclarations = [...registry.values()].filter(\n (e) => e.fileName === id,\n );\n if (fileDeclarations.length > 0) {\n const localDepClassNames = fileDeclarations.map((e) => e.className);\n outputCode += generateHmrCode(fileDeclarations, localDepClassNames);\n }\n }\n\n return { code: outputCode, map: result.map };\n }\n\n function resolveTsConfigPath() {\n const { root, isProd, isLib } = tsConfigResolutionContext!;\n return getTsConfigPath(\n root,\n pluginOptions.tsconfigGetter(),\n isProd,\n pluginOptions.isTest,\n isLib,\n pluginOptions.workspaceRoot,\n );\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-fast-compile',\n enforce: 'pre' as const,\n async config(config, { command }) {\n watchMode = command === 'serve';\n const isProd = isProdMode(config.mode);\n\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n const preliminaryTsConfigPath = resolveTsConfigPath();\n\n const depOptimizer = createDepOptimizerConfig({\n tsconfig: preliminaryTsConfigPath,\n isProd,\n jit: pluginOptions.jit,\n watchMode,\n isTest: pluginOptions.isTest,\n isAstroIntegration: pluginOptions.isAstroIntegration,\n });\n\n // No `resolve.conditions` extension here: the `style` condition is\n // scoped to `.css`-extension requests by\n // `cssExtensionStyleResolverPlugin`, registered once at the\n // `angular()` factory level (which is the only public entry point\n // that wires this plugin in).\n return {\n ...(vite.rolldownVersion ? { oxc: {} as any } : { esbuild: false }),\n ...depOptimizer,\n };\n },\n configResolved(config) {\n resolvedConfig = config;\n },\n configureServer(server) {\n // Watch for new .ts files and scan them into the registry. Use\n // the barrel-aware scanner so a newly added re-export entry\n // (`export * from './x'`) also expands its underlying directive\n // classes — otherwise the registry stays stale until restart.\n server.watcher.on('add', async (filePath) => {\n if (\n filePath.endsWith('.ts') &&\n !filePath.endsWith('.spec.ts') &&\n !filePath.endsWith('.d.ts')\n ) {\n await scanBarrelExports(filePath, new Set(), true);\n }\n });\n },\n async buildStart() {\n await initFastCompile();\n },\n async handleHotUpdate(ctx) {\n // Resource file changes → invalidate parent .ts module\n if (resourceToSource.has(ctx.file)) {\n const parentSource = resourceToSource.get(ctx.file)!;\n const parentModule = ctx.server.moduleGraph.getModuleById(parentSource);\n if (parentModule) {\n return [parentModule];\n }\n }\n\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n\n // Remove old entries from this file\n const oldEntries = [...registry.entries()]\n .filter(([_, v]) => v.fileName === fileId)\n .map(([k]) => k);\n for (const key of oldEntries) {\n registry.delete(key);\n }\n\n // Rescan the changed file via the barrel-aware scanner so an\n // edited barrel re-export picks up newly-referenced files.\n // Pass overwrite=true so updated metadata replaces stale\n // entries from the previous scan.\n await scanBarrelExports(fileId, new Set(), true);\n }\n\n // Let Vite handle the rest — the transform hook will recompile\n return ctx.modules;\n },\n resolveId(id, importer) {\n if (id.startsWith(VIRTUAL_RAW_PREFIX)) {\n return `\\0${id}`;\n }\n\n if (pluginOptions.jit && id.startsWith('angular:jit:')) {\n const filePath = normalizePath(\n resolve(dirname(importer as string), id.split(';')[1]),\n );\n if (id.includes(':style')) {\n markStylePathSafe(resolvedConfig, filePath);\n return filePath + '?inline';\n }\n return toVirtualRawId(filePath);\n }\n\n const rawRewrite = rewriteHtmlRawImport(id, importer);\n if (rawRewrite) return rawRewrite;\n\n // User `.scss?inline` / `.css?inline` imports: resolve and mark\n // safe so Vite's native CSS pipeline handles them.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id) && importer) {\n const filePath = id.split('?')[0];\n const resolved = isAbsolute(filePath)\n ? normalizePath(filePath)\n : normalizePath(resolve(dirname(importer), filePath));\n markStylePathSafe(resolvedConfig, resolved);\n return resolved + '?inline';\n }\n\n return undefined;\n },\n async load(id) {\n const rawModule = await loadVirtualRawModule(this, id);\n if (rawModule !== undefined) return rawModule;\n\n // Vitest fallback: module-runner can skip resolveId, so the bare\n // ?inline query reaches load. Mark safe and let Vite handle it.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id)) {\n markStylePathSafe(resolvedConfig, id.split('?')[0]);\n }\n\n return;\n },\n transform: {\n filter: {\n id: {\n include: [TS_EXT_REGEX],\n // `?raw` ids already carry Vite's native raw-loader output\n // (`export default \"<source>\"`). Recompiling them as Angular/TS\n // would strip that default export, so leave them to Vite (#2356).\n exclude: [\n /node_modules/,\n 'type=script',\n '@ng/component',\n /[?&]raw\\b/,\n ],\n },\n },\n async handler(code, id) {\n if (\n pluginOptions.transformFilter &&\n !(pluginOptions.transformFilter(code, id) ?? true)\n ) {\n return;\n }\n\n if (id.includes('.ts?')) {\n id = id.replace(/\\?(.*)/, '');\n }\n return handleFastCompileTransform(code, id);\n },\n },\n };\n}\n"],"mappings":"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"}
|
package/src/lib/host.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import * as ts from
|
|
2
|
-
import type
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import { type StylePreprocessor } from "./style-preprocessor.js";
|
|
3
|
+
import { AnalogStylesheetRegistry } from "./stylesheet-registry.js";
|
|
4
|
+
import type { SourceFileCache } from "./utils/source-file-cache.js";
|
|
3
5
|
export declare function augmentHostWithResources(host: ts.CompilerHost, transform: (code: string, id: string, options?: {
|
|
4
|
-
|
|
6
|
+
ssr?: boolean;
|
|
5
7
|
}) => ReturnType<any> | null, options: {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
inlineStylesExtension: string;
|
|
9
|
+
isProd?: boolean;
|
|
10
|
+
stylesheetRegistry?: AnalogStylesheetRegistry;
|
|
11
|
+
sourceFileCache?: SourceFileCache;
|
|
12
|
+
stylePreprocessor?: StylePreprocessor;
|
|
11
13
|
}): void;
|
|
12
14
|
export declare function augmentProgramWithVersioning(program: ts.Program): void;
|
|
13
15
|
export declare function augmentHostWithCaching(host: ts.CompilerHost, cache: Map<string, ts.SourceFile>): void;
|