@analogjs/vite-plugin-angular 3.0.0-alpha.8 → 3.0.0-alpha.9
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/package.json +3 -7
- package/setup-vitest.js +154 -193
- package/setup-vitest.js.map +1 -1
- package/src/index.d.ts +1 -1
- package/src/index.js +6 -2
- package/src/index.js.map +1 -1
- package/src/lib/angular-build-optimizer-plugin.js +48 -63
- package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
- package/src/lib/angular-jit-plugin.js +31 -37
- package/src/lib/angular-jit-plugin.js.map +1 -1
- 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.js +790 -1077
- package/src/lib/angular-vite-plugin.js.map +1 -1
- package/src/lib/angular-vitest-plugin.js +97 -135
- package/src/lib/angular-vitest-plugin.js.map +1 -1
- package/src/lib/compiler-plugin.js +40 -44
- package/src/lib/compiler-plugin.js.map +1 -1
- package/src/lib/component-resolvers.js +87 -120
- package/src/lib/component-resolvers.js.map +1 -1
- package/src/lib/host.js +69 -101
- package/src/lib/host.js.map +1 -1
- package/src/lib/live-reload-plugin.js +51 -63
- package/src/lib/live-reload-plugin.js.map +1 -1
- 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.js +35 -62
- package/src/lib/plugins/file-replacements.plugin.js.map +1 -1
- package/src/lib/router-plugin.js +23 -23
- package/src/lib/router-plugin.js.map +1 -1
- package/src/lib/tools/package.json +2 -5
- package/src/lib/tools/src/builders/vite/vite-build.impl.js +31 -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 +52 -60
- 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/devkit.js +34 -38
- package/src/lib/utils/devkit.js.map +1 -1
- package/src/lib/utils/rolldown.js +9 -5
- package/src/lib/utils/rolldown.js.map +1 -1
- package/src/lib/utils/source-file-cache.js +35 -37
- package/src/lib/utils/source-file-cache.js.map +1 -1
- package/README.md +0 -91
- 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.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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler-plugin.js","
|
|
1
|
+
{"version":3,"file":"compiler-plugin.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/compiler-plugin.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { DepOptimizationConfig, Rolldown } from 'vite';\nimport type { PluginBuild } from 'esbuild';\n\nimport {\n CompilerPluginOptions,\n JavaScriptTransformer,\n} from './utils/devkit.js';\n\ntype EsbuildOptions = NonNullable<DepOptimizationConfig['esbuildOptions']>;\ntype EsbuildPlugin = NonNullable<EsbuildOptions['plugins']>[number];\n\nexport function createCompilerPlugin(\n pluginOptions: CompilerPluginOptions,\n isTest: boolean,\n closeTransformer: boolean,\n): EsbuildPlugin {\n const javascriptTransformer = new JavaScriptTransformer(\n { ...pluginOptions, jit: true },\n 1,\n );\n\n return {\n name: 'analogjs-angular-esbuild-deps-optimizer-plugin',\n async setup(build: PluginBuild) {\n if (!isTest) {\n build.onLoad({ filter: /\\.[cm]?js$/ }, async (args) => {\n const contents = await javascriptTransformer.transformFile(args.path);\n\n return {\n contents,\n loader: 'js',\n };\n });\n }\n\n if (closeTransformer) {\n build.onEnd(() => javascriptTransformer.close());\n }\n },\n };\n}\n\nexport function createRolldownCompilerPlugin(\n pluginOptions: CompilerPluginOptions,\n): Rolldown.Plugin {\n const javascriptTransformer = new JavaScriptTransformer(\n { ...pluginOptions, jit: true },\n 1,\n );\n return {\n name: 'analogjs-rolldown-deps-optimizer-plugin',\n load: {\n filter: {\n id: /\\.[cm]?js$/,\n },\n async handler(id) {\n const contents = await javascriptTransformer.transformFile(id);\n\n return {\n code: Buffer.from(contents).toString('utf-8'),\n loader: 'js',\n } as any;\n },\n },\n };\n}\n"],"mappings":";;AAmBA,SAAgB,qBACd,eACA,QACA,kBACe;CACf,MAAM,wBAAwB,IAAI,GAChC;EAAE,GAAG;EAAe,KAAK;EAAM,EAC/B,EACD;AAED,QAAO;EACL,MAAM;EACN,MAAM,MAAM,OAAoB;AAC9B,OAAI,CAAC,OACH,OAAM,OAAO,EAAE,QAAQ,cAAc,EAAE,OAAO,SAAS;AAGrD,WAAO;KACL,UAHe,MAAM,sBAAsB,cAAc,KAAK,KAAK;KAInE,QAAQ;KACT;KACD;AAGJ,OAAI,iBACF,OAAM,YAAY,sBAAsB,OAAO,CAAC;;EAGrD;;AAGH,SAAgB,6BACd,eACiB;CACjB,MAAM,wBAAwB,IAAI,GAChC;EAAE,GAAG;EAAe,KAAK;EAAM,EAC/B,EACD;AACD,QAAO;EACL,MAAM;EACN,MAAM;GACJ,QAAQ,EACN,IAAI,cACL;GACD,MAAM,QAAQ,IAAI;IAChB,MAAM,WAAW,MAAM,sBAAsB,cAAc,GAAG;AAE9D,WAAO;KACL,MAAM,OAAO,KAAK,SAAS,CAAC,SAAS,QAAQ;KAC7C,QAAQ;KACT;;GAEJ;EACF"}
|
|
@@ -1,131 +1,98 @@
|
|
|
1
|
-
import { dirname, resolve } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { parseSync } from 'oxc-parser';
|
|
7
|
-
import { Visitor } from 'rolldown/utils';
|
|
8
|
-
import { normalizePath } from 'vite';
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
// AST helpers
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
1
|
+
import { dirname, resolve } from "node:path";
|
|
2
|
+
import { normalizePath } from "vite";
|
|
3
|
+
import { parseSync } from "oxc-parser";
|
|
4
|
+
import { Visitor } from "rolldown/utils";
|
|
5
|
+
//#region packages/vite-plugin-angular/src/lib/component-resolvers.ts
|
|
12
6
|
/**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
* Extracts a string value from an ESTree AST node.
|
|
8
|
+
*
|
|
9
|
+
* Handles three forms that Angular decorators may use:
|
|
10
|
+
* - `Literal` with a string value → `'./foo.css'` / `"./foo.css"`
|
|
11
|
+
* - `StringLiteral` (OXC-specific) → same representation
|
|
12
|
+
* - `TemplateLiteral` with zero expressions → `` `./foo.css` ``
|
|
13
|
+
*
|
|
14
|
+
* Uses `any` because OXC's AST mixes standard ESTree nodes with
|
|
15
|
+
* OXC-specific variants (e.g. `StringLiteral`), and the project's
|
|
16
|
+
* tsconfig enforces `noPropertyAccessFromIndexSignature`.
|
|
17
|
+
*/
|
|
25
18
|
function getStringValue(node) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return node.value;
|
|
31
|
-
}
|
|
32
|
-
// OXC-specific StringLiteral node
|
|
33
|
-
if (node.type === 'StringLiteral') {
|
|
34
|
-
return node.value;
|
|
35
|
-
}
|
|
36
|
-
// Template literal with no interpolation (e.g., `./foo.css`)
|
|
37
|
-
if (node.type === 'TemplateLiteral' &&
|
|
38
|
-
node.expressions.length === 0 &&
|
|
39
|
-
node.quasis.length === 1) {
|
|
40
|
-
return node.quasis[0].value.cooked ?? node.quasis[0].value.raw;
|
|
41
|
-
}
|
|
42
|
-
return undefined;
|
|
19
|
+
if (!node) return void 0;
|
|
20
|
+
if (node.type === "Literal" && typeof node.value === "string") return node.value;
|
|
21
|
+
if (node.type === "StringLiteral") return node.value;
|
|
22
|
+
if (node.type === "TemplateLiteral" && node.expressions.length === 0 && node.quasis.length === 1) return node.quasis[0].value.cooked ?? node.quasis[0].value.raw;
|
|
43
23
|
}
|
|
44
24
|
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
25
|
+
* Parses TypeScript/JS source with OXC and collects `styleUrl`, `styleUrls`,
|
|
26
|
+
* and `templateUrl` property values from Angular `@Component()` decorators
|
|
27
|
+
* in a single AST pass.
|
|
28
|
+
*
|
|
29
|
+
* This replaces the previous ts-morph implementation — OXC parses natively
|
|
30
|
+
* via Rust NAPI bindings, avoiding the overhead of spinning up a full
|
|
31
|
+
* TypeScript `Project` for each file.
|
|
32
|
+
*/
|
|
53
33
|
function collectComponentUrls(code) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
if (name === 'templateUrl') {
|
|
79
|
-
const val = getStringValue(node.value);
|
|
80
|
-
if (val !== undefined)
|
|
81
|
-
templateUrls.push(val);
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
visitor.visit(program);
|
|
86
|
-
return { styleUrls, templateUrls };
|
|
34
|
+
const { program } = parseSync("cmp.ts", code);
|
|
35
|
+
const styleUrls = [];
|
|
36
|
+
const templateUrls = [];
|
|
37
|
+
new Visitor({ Property(node) {
|
|
38
|
+
if (node.key?.type !== "Identifier") return;
|
|
39
|
+
const name = node.key.name;
|
|
40
|
+
if (name === "styleUrls" && node.value?.type === "ArrayExpression") for (const el of node.value.elements) {
|
|
41
|
+
const val = getStringValue(el);
|
|
42
|
+
if (val !== void 0) styleUrls.push(val);
|
|
43
|
+
}
|
|
44
|
+
if (name === "styleUrl") {
|
|
45
|
+
const val = getStringValue(node.value);
|
|
46
|
+
if (val !== void 0) styleUrls.push(val);
|
|
47
|
+
}
|
|
48
|
+
if (name === "templateUrl") {
|
|
49
|
+
const val = getStringValue(node.value);
|
|
50
|
+
if (val !== void 0) templateUrls.push(val);
|
|
51
|
+
}
|
|
52
|
+
} }).visit(program);
|
|
53
|
+
return {
|
|
54
|
+
styleUrls,
|
|
55
|
+
templateUrls
|
|
56
|
+
};
|
|
87
57
|
}
|
|
88
58
|
/** Extract all `styleUrl` / `styleUrls` values from Angular component source. */
|
|
89
|
-
|
|
90
|
-
|
|
59
|
+
function getStyleUrls(code) {
|
|
60
|
+
return collectComponentUrls(code).styleUrls;
|
|
91
61
|
}
|
|
92
62
|
/** Extract all `templateUrl` values from Angular component source. */
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
export class StyleUrlsResolver {
|
|
97
|
-
// These resolvers may be called multiple times during the same
|
|
98
|
-
// compilation for the same files. Caching is required because these
|
|
99
|
-
// resolvers use synchronous system calls to the filesystem, which can
|
|
100
|
-
// degrade performance when running compilations for multiple files.
|
|
101
|
-
styleUrlsCache = new Map();
|
|
102
|
-
resolve(code, id) {
|
|
103
|
-
const matchedStyleUrls = getStyleUrls(code);
|
|
104
|
-
const entry = this.styleUrlsCache.get(id);
|
|
105
|
-
// We're using `matchedStyleUrls` as a key because the code may be changing continuously,
|
|
106
|
-
// resulting in the resolver being called multiple times. While the code changes, the
|
|
107
|
-
// `styleUrls` may remain constant, which means we should always return the previously
|
|
108
|
-
// resolved style URLs.
|
|
109
|
-
if (entry && entry.matchedStyleUrls === matchedStyleUrls) {
|
|
110
|
-
return entry.styleUrls;
|
|
111
|
-
}
|
|
112
|
-
const styleUrls = matchedStyleUrls.map((styleUrlPath) => {
|
|
113
|
-
return `${styleUrlPath}|${normalizePath(resolve(dirname(id), styleUrlPath))}`;
|
|
114
|
-
});
|
|
115
|
-
this.styleUrlsCache.set(id, { styleUrls, matchedStyleUrls });
|
|
116
|
-
return styleUrls;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
export class TemplateUrlsResolver {
|
|
120
|
-
templateUrlsCache = new Map();
|
|
121
|
-
resolve(code, id) {
|
|
122
|
-
const entry = this.templateUrlsCache.get(id);
|
|
123
|
-
if (entry?.code === code) {
|
|
124
|
-
return entry.templateUrlPaths;
|
|
125
|
-
}
|
|
126
|
-
const templateUrlPaths = getTemplateUrls(code).map((url) => `${url}|${normalizePath(resolve(dirname(id), url))}`);
|
|
127
|
-
this.templateUrlsCache.set(id, { code, templateUrlPaths });
|
|
128
|
-
return templateUrlPaths;
|
|
129
|
-
}
|
|
63
|
+
function getTemplateUrls(code) {
|
|
64
|
+
return collectComponentUrls(code).templateUrls;
|
|
130
65
|
}
|
|
66
|
+
var StyleUrlsResolver = class {
|
|
67
|
+
styleUrlsCache = /* @__PURE__ */ new Map();
|
|
68
|
+
resolve(code, id) {
|
|
69
|
+
const matchedStyleUrls = getStyleUrls(code);
|
|
70
|
+
const entry = this.styleUrlsCache.get(id);
|
|
71
|
+
if (entry && entry.matchedStyleUrls === matchedStyleUrls) return entry.styleUrls;
|
|
72
|
+
const styleUrls = matchedStyleUrls.map((styleUrlPath) => {
|
|
73
|
+
return `${styleUrlPath}|${normalizePath(resolve(dirname(id), styleUrlPath))}`;
|
|
74
|
+
});
|
|
75
|
+
this.styleUrlsCache.set(id, {
|
|
76
|
+
styleUrls,
|
|
77
|
+
matchedStyleUrls
|
|
78
|
+
});
|
|
79
|
+
return styleUrls;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
var TemplateUrlsResolver = class {
|
|
83
|
+
templateUrlsCache = /* @__PURE__ */ new Map();
|
|
84
|
+
resolve(code, id) {
|
|
85
|
+
const entry = this.templateUrlsCache.get(id);
|
|
86
|
+
if (entry?.code === code) return entry.templateUrlPaths;
|
|
87
|
+
const templateUrlPaths = getTemplateUrls(code).map((url) => `${url}|${normalizePath(resolve(dirname(id), url))}`);
|
|
88
|
+
this.templateUrlsCache.set(id, {
|
|
89
|
+
code,
|
|
90
|
+
templateUrlPaths
|
|
91
|
+
});
|
|
92
|
+
return templateUrlPaths;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
//#endregion
|
|
96
|
+
export { StyleUrlsResolver, TemplateUrlsResolver };
|
|
97
|
+
|
|
131
98
|
//# sourceMappingURL=component-resolvers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-resolvers.js","
|
|
1
|
+
{"version":3,"file":"component-resolvers.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/component-resolvers.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path';\n// OXC parser (native Rust, NAPI-RS) replaces ts-morph for AST extraction.\n// It is ~10-50x faster for the narrow task of pulling property values from\n// Angular component decorators. The Visitor helper from Rolldown walks the\n// ESTree-compatible AST that OXC produces.\nimport { parseSync } from 'oxc-parser';\nimport { Visitor } from 'rolldown/utils';\nimport { normalizePath } from 'vite';\n\n// ---------------------------------------------------------------------------\n// AST helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts a string value from an ESTree AST node.\n *\n * Handles three forms that Angular decorators may use:\n * - `Literal` with a string value → `'./foo.css'` / `\"./foo.css\"`\n * - `StringLiteral` (OXC-specific) → same representation\n * - `TemplateLiteral` with zero expressions → `` `./foo.css` ``\n *\n * Uses `any` because OXC's AST mixes standard ESTree nodes with\n * OXC-specific variants (e.g. `StringLiteral`), and the project's\n * tsconfig enforces `noPropertyAccessFromIndexSignature`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getStringValue(node: any): string | undefined {\n if (!node) return undefined;\n // Standard ESTree Literal (string value)\n if (node.type === 'Literal' && typeof node.value === 'string') {\n return node.value;\n }\n // OXC-specific StringLiteral node\n if (node.type === 'StringLiteral') {\n return node.value;\n }\n // Template literal with no interpolation (e.g., `./foo.css`)\n if (\n node.type === 'TemplateLiteral' &&\n node.expressions.length === 0 &&\n node.quasis.length === 1\n ) {\n return node.quasis[0].value.cooked ?? node.quasis[0].value.raw;\n }\n return undefined;\n}\n\n/**\n * Parses TypeScript/JS source with OXC and collects `styleUrl`, `styleUrls`,\n * and `templateUrl` property values from Angular `@Component()` decorators\n * in a single AST pass.\n *\n * This replaces the previous ts-morph implementation — OXC parses natively\n * via Rust NAPI bindings, avoiding the overhead of spinning up a full\n * TypeScript `Project` for each file.\n */\nfunction collectComponentUrls(code: string): {\n styleUrls: string[];\n templateUrls: string[];\n} {\n const { program } = parseSync('cmp.ts', code);\n const styleUrls: string[] = [];\n const templateUrls: string[] = [];\n\n const visitor = new Visitor({\n // The Visitor callback receives raw ESTree nodes. We use `any`\n // because OXC's AST includes non-standard node variants and the\n // project tsconfig enforces `noPropertyAccessFromIndexSignature`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Property(node: any) {\n if (node.key?.type !== 'Identifier') return;\n const name: string = node.key.name;\n\n if (name === 'styleUrls' && node.value?.type === 'ArrayExpression') {\n for (const el of node.value.elements) {\n const val = getStringValue(el);\n if (val !== undefined) styleUrls.push(val);\n }\n }\n\n if (name === 'styleUrl') {\n const val = getStringValue(node.value);\n if (val !== undefined) styleUrls.push(val);\n }\n\n if (name === 'templateUrl') {\n const val = getStringValue(node.value);\n if (val !== undefined) templateUrls.push(val);\n }\n },\n });\n visitor.visit(program);\n\n return { styleUrls, templateUrls };\n}\n\n/** Extract all `styleUrl` / `styleUrls` values from Angular component source. */\nexport function getStyleUrls(code: string): string[] {\n return collectComponentUrls(code).styleUrls;\n}\n\n/** Extract all `templateUrl` values from Angular component source. */\nexport function getTemplateUrls(code: string): string[] {\n return collectComponentUrls(code).templateUrls;\n}\n\n// ---------------------------------------------------------------------------\n// Resolver caches\n// ---------------------------------------------------------------------------\n\ninterface StyleUrlsCacheEntry {\n matchedStyleUrls: string[];\n styleUrls: string[];\n}\n\nexport class StyleUrlsResolver {\n // These resolvers may be called multiple times during the same\n // compilation for the same files. Caching is required because these\n // resolvers use synchronous system calls to the filesystem, which can\n // degrade performance when running compilations for multiple files.\n private readonly styleUrlsCache = new Map<string, StyleUrlsCacheEntry>();\n\n resolve(code: string, id: string): string[] {\n const matchedStyleUrls = getStyleUrls(code);\n const entry = this.styleUrlsCache.get(id);\n // We're using `matchedStyleUrls` as a key because the code may be changing continuously,\n // resulting in the resolver being called multiple times. While the code changes, the\n // `styleUrls` may remain constant, which means we should always return the previously\n // resolved style URLs.\n if (entry && entry.matchedStyleUrls === matchedStyleUrls) {\n return entry.styleUrls;\n }\n\n const styleUrls = matchedStyleUrls.map((styleUrlPath) => {\n return `${styleUrlPath}|${normalizePath(\n resolve(dirname(id), styleUrlPath),\n )}`;\n });\n\n this.styleUrlsCache.set(id, { styleUrls, matchedStyleUrls });\n return styleUrls;\n }\n}\n\ninterface TemplateUrlsCacheEntry {\n code: string;\n templateUrlPaths: string[];\n}\n\nexport class TemplateUrlsResolver {\n private readonly templateUrlsCache = new Map<\n string,\n TemplateUrlsCacheEntry\n >();\n\n resolve(code: string, id: string): string[] {\n const entry = this.templateUrlsCache.get(id);\n if (entry?.code === code) {\n return entry.templateUrlPaths;\n }\n\n const templateUrlPaths = getTemplateUrls(code).map(\n (url) => `${url}|${normalizePath(resolve(dirname(id), url))}`,\n );\n\n this.templateUrlsCache.set(id, { code, templateUrlPaths });\n return templateUrlPaths;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,SAAS,eAAe,MAA+B;AACrD,KAAI,CAAC,KAAM,QAAO,KAAA;AAElB,KAAI,KAAK,SAAS,aAAa,OAAO,KAAK,UAAU,SACnD,QAAO,KAAK;AAGd,KAAI,KAAK,SAAS,gBAChB,QAAO,KAAK;AAGd,KACE,KAAK,SAAS,qBACd,KAAK,YAAY,WAAW,KAC5B,KAAK,OAAO,WAAW,EAEvB,QAAO,KAAK,OAAO,GAAG,MAAM,UAAU,KAAK,OAAO,GAAG,MAAM;;;;;;;;;;;AAc/D,SAAS,qBAAqB,MAG5B;CACA,MAAM,EAAE,YAAY,UAAU,UAAU,KAAK;CAC7C,MAAM,YAAsB,EAAE;CAC9B,MAAM,eAAyB,EAAE;AAEjB,KAAI,QAAQ,EAK1B,SAAS,MAAW;AAClB,MAAI,KAAK,KAAK,SAAS,aAAc;EACrC,MAAM,OAAe,KAAK,IAAI;AAE9B,MAAI,SAAS,eAAe,KAAK,OAAO,SAAS,kBAC/C,MAAK,MAAM,MAAM,KAAK,MAAM,UAAU;GACpC,MAAM,MAAM,eAAe,GAAG;AAC9B,OAAI,QAAQ,KAAA,EAAW,WAAU,KAAK,IAAI;;AAI9C,MAAI,SAAS,YAAY;GACvB,MAAM,MAAM,eAAe,KAAK,MAAM;AACtC,OAAI,QAAQ,KAAA,EAAW,WAAU,KAAK,IAAI;;AAG5C,MAAI,SAAS,eAAe;GAC1B,MAAM,MAAM,eAAe,KAAK,MAAM;AACtC,OAAI,QAAQ,KAAA,EAAW,cAAa,KAAK,IAAI;;IAGlD,CAAC,CACM,MAAM,QAAQ;AAEtB,QAAO;EAAE;EAAW;EAAc;;;AAIpC,SAAgB,aAAa,MAAwB;AACnD,QAAO,qBAAqB,KAAK,CAAC;;;AAIpC,SAAgB,gBAAgB,MAAwB;AACtD,QAAO,qBAAqB,KAAK,CAAC;;AAYpC,IAAa,oBAAb,MAA+B;CAK7B,iCAAkC,IAAI,KAAkC;CAExE,QAAQ,MAAc,IAAsB;EAC1C,MAAM,mBAAmB,aAAa,KAAK;EAC3C,MAAM,QAAQ,KAAK,eAAe,IAAI,GAAG;AAKzC,MAAI,SAAS,MAAM,qBAAqB,iBACtC,QAAO,MAAM;EAGf,MAAM,YAAY,iBAAiB,KAAK,iBAAiB;AACvD,UAAO,GAAG,aAAa,GAAG,cACxB,QAAQ,QAAQ,GAAG,EAAE,aAAa,CACnC;IACD;AAEF,OAAK,eAAe,IAAI,IAAI;GAAE;GAAW;GAAkB,CAAC;AAC5D,SAAO;;;AASX,IAAa,uBAAb,MAAkC;CAChC,oCAAqC,IAAI,KAGtC;CAEH,QAAQ,MAAc,IAAsB;EAC1C,MAAM,QAAQ,KAAK,kBAAkB,IAAI,GAAG;AAC5C,MAAI,OAAO,SAAS,KAClB,QAAO,MAAM;EAGf,MAAM,mBAAmB,gBAAgB,KAAK,CAAC,KAC5C,QAAQ,GAAG,IAAI,GAAG,cAAc,QAAQ,QAAQ,GAAG,EAAE,IAAI,CAAC,GAC5D;AAED,OAAK,kBAAkB,IAAI,IAAI;GAAE;GAAM;GAAkB,CAAC;AAC1D,SAAO"}
|
package/src/lib/host.js
CHANGED
|
@@ -1,108 +1,76 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
console.error(`${e}`);
|
|
42
|
-
}
|
|
43
|
-
return { content: stylesheetResult?.code || '' };
|
|
44
|
-
};
|
|
45
|
-
resourceHost.resourceNameToFileName = function (resourceName, containingFile) {
|
|
46
|
-
const resolvedPath = path.join(path.dirname(containingFile), resourceName);
|
|
47
|
-
// All resource names that have template file extensions are assumed to be templates
|
|
48
|
-
if (!options.externalComponentStyles || !hasStyleExtension(resolvedPath)) {
|
|
49
|
-
return resolvedPath;
|
|
50
|
-
}
|
|
51
|
-
// For external stylesheets, create a unique identifier and store the mapping
|
|
52
|
-
let externalId = options.externalComponentStyles.get(resolvedPath);
|
|
53
|
-
externalId ??= createHash('sha256').update(resolvedPath).digest('hex');
|
|
54
|
-
const filename = externalId + path.extname(resolvedPath);
|
|
55
|
-
options.externalComponentStyles.set(filename, resolvedPath);
|
|
56
|
-
return filename;
|
|
57
|
-
};
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { normalizePath } from "vite";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
//#region packages/vite-plugin-angular/src/lib/host.ts
|
|
5
|
+
function augmentHostWithResources(host, transform, options) {
|
|
6
|
+
const resourceHost = host;
|
|
7
|
+
resourceHost.readResource = async function(fileName) {
|
|
8
|
+
const filePath = normalizePath(fileName);
|
|
9
|
+
const content = this.readFile(filePath);
|
|
10
|
+
if (content === void 0) throw new Error("Unable to locate component resource: " + fileName);
|
|
11
|
+
return content;
|
|
12
|
+
};
|
|
13
|
+
resourceHost.getModifiedResourceFiles = function() {
|
|
14
|
+
return options?.sourceFileCache?.modifiedFiles;
|
|
15
|
+
};
|
|
16
|
+
resourceHost.transformResource = async function(data, context) {
|
|
17
|
+
if (context.type !== "style") return null;
|
|
18
|
+
if (options.inlineComponentStyles) {
|
|
19
|
+
const filename = createHash("sha256").update(context.containingFile).update(context.className).update(String(context.order)).update(data).digest("hex") + "." + options.inlineStylesExtension;
|
|
20
|
+
options.inlineComponentStyles.set(filename, data);
|
|
21
|
+
return { content: filename };
|
|
22
|
+
}
|
|
23
|
+
const filename = context.resourceFile ?? context.containingFile.replace(".ts", `.${options?.inlineStylesExtension}`);
|
|
24
|
+
let stylesheetResult;
|
|
25
|
+
try {
|
|
26
|
+
stylesheetResult = await transform(data, `${filename}?direct`);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error(`${e}`);
|
|
29
|
+
}
|
|
30
|
+
return { content: stylesheetResult?.code || "" };
|
|
31
|
+
};
|
|
32
|
+
resourceHost.resourceNameToFileName = function(resourceName, containingFile) {
|
|
33
|
+
const resolvedPath = path.join(path.dirname(containingFile), resourceName);
|
|
34
|
+
if (!options.externalComponentStyles || !hasStyleExtension(resolvedPath)) return resolvedPath;
|
|
35
|
+
let externalId = options.externalComponentStyles.get(resolvedPath);
|
|
36
|
+
externalId ??= createHash("sha256").update(resolvedPath).digest("hex");
|
|
37
|
+
const filename = externalId + path.extname(resolvedPath);
|
|
38
|
+
options.externalComponentStyles.set(filename, resolvedPath);
|
|
39
|
+
return filename;
|
|
40
|
+
};
|
|
58
41
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return files;
|
|
67
|
-
};
|
|
42
|
+
function augmentProgramWithVersioning(program) {
|
|
43
|
+
const baseGetSourceFiles = program.getSourceFiles;
|
|
44
|
+
program.getSourceFiles = function(...parameters) {
|
|
45
|
+
const files = baseGetSourceFiles(...parameters);
|
|
46
|
+
for (const file of files) file.version ??= createHash("sha256").update(file.text).digest("hex");
|
|
47
|
+
return files;
|
|
48
|
+
};
|
|
68
49
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
cache.set(fileName, file);
|
|
78
|
-
}
|
|
79
|
-
return file;
|
|
80
|
-
};
|
|
50
|
+
function augmentHostWithCaching(host, cache) {
|
|
51
|
+
const baseGetSourceFile = host.getSourceFile;
|
|
52
|
+
host.getSourceFile = function(fileName, languageVersion, onError, shouldCreateNewSourceFile, ...parameters) {
|
|
53
|
+
if (!shouldCreateNewSourceFile && cache.has(fileName)) return cache.get(fileName);
|
|
54
|
+
const file = baseGetSourceFile.call(host, fileName, languageVersion, onError, true, ...parameters);
|
|
55
|
+
if (file) cache.set(fileName, file);
|
|
56
|
+
return file;
|
|
57
|
+
};
|
|
81
58
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
result.after = [...(first.after || []), ...(second.after || [])];
|
|
89
|
-
}
|
|
90
|
-
if (first.afterDeclarations || second.afterDeclarations) {
|
|
91
|
-
result.afterDeclarations = [
|
|
92
|
-
...(first.afterDeclarations || []),
|
|
93
|
-
...(second.afterDeclarations || []),
|
|
94
|
-
];
|
|
95
|
-
}
|
|
96
|
-
return result;
|
|
59
|
+
function mergeTransformers(first, second) {
|
|
60
|
+
const result = {};
|
|
61
|
+
if (first.before || second.before) result.before = [...first.before || [], ...second.before || []];
|
|
62
|
+
if (first.after || second.after) result.after = [...first.after || [], ...second.after || []];
|
|
63
|
+
if (first.afterDeclarations || second.afterDeclarations) result.afterDeclarations = [...first.afterDeclarations || [], ...second.afterDeclarations || []];
|
|
64
|
+
return result;
|
|
97
65
|
}
|
|
98
66
|
function hasStyleExtension(file) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
default:
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
67
|
+
switch (path.extname(file).toLowerCase()) {
|
|
68
|
+
case ".css":
|
|
69
|
+
case ".scss": return true;
|
|
70
|
+
default: return false;
|
|
71
|
+
}
|
|
107
72
|
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { augmentHostWithCaching, augmentHostWithResources, augmentProgramWithVersioning, mergeTransformers };
|
|
75
|
+
|
|
108
76
|
//# sourceMappingURL=host.js.map
|
package/src/lib/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","
|
|
1
|
+
{"version":3,"file":"host.js","names":[],"sources":["../../../../../packages/vite-plugin-angular/src/lib/host.ts"],"sourcesContent":["import type { CompilerHost } from '@angular/compiler-cli';\nimport { normalizePath } from 'vite';\n\nimport * as ts from 'typescript';\n\nimport { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport type { SourceFileCache } from './utils/source-file-cache.js';\n\nexport function augmentHostWithResources(\n host: ts.CompilerHost,\n transform: (\n code: string,\n id: string,\n options?: { ssr?: boolean },\n ) => ReturnType<any> | null,\n options: {\n inlineStylesExtension: string;\n isProd?: boolean;\n inlineComponentStyles?: Map<string, string>;\n externalComponentStyles?: Map<string, string>;\n sourceFileCache?: SourceFileCache;\n },\n): void {\n const resourceHost = host as CompilerHost;\n\n resourceHost.readResource = async function (fileName: string) {\n const filePath = normalizePath(fileName);\n\n const content = (this as any).readFile(filePath);\n\n if (content === undefined) {\n throw new Error('Unable to locate component resource: ' + fileName);\n }\n\n return content;\n };\n\n resourceHost.getModifiedResourceFiles = function () {\n return options?.sourceFileCache?.modifiedFiles;\n };\n\n resourceHost.transformResource = async function (data, context) {\n // Only style resources are supported currently\n if (context.type !== 'style') {\n return null;\n }\n\n if (options.inlineComponentStyles) {\n const id = createHash('sha256')\n .update(context.containingFile)\n .update(context.className)\n .update(String(context.order))\n .update(data)\n .digest('hex');\n const filename = id + '.' + options.inlineStylesExtension;\n options.inlineComponentStyles.set(filename, data);\n return { content: filename };\n }\n\n // Resource file only exists for external stylesheets\n const filename =\n context.resourceFile ??\n context.containingFile.replace(\n '.ts',\n `.${options?.inlineStylesExtension}`,\n );\n\n let stylesheetResult;\n\n try {\n stylesheetResult = await transform(data, `${filename}?direct`);\n } catch (e) {\n console.error(`${e}`);\n }\n\n return { content: stylesheetResult?.code || '' };\n };\n\n resourceHost.resourceNameToFileName = function (\n resourceName,\n containingFile,\n ) {\n const resolvedPath = path.join(path.dirname(containingFile), resourceName);\n\n // All resource names that have template file extensions are assumed to be templates\n if (!options.externalComponentStyles || !hasStyleExtension(resolvedPath)) {\n return resolvedPath;\n }\n\n // For external stylesheets, create a unique identifier and store the mapping\n let externalId = options.externalComponentStyles.get(resolvedPath);\n externalId ??= createHash('sha256').update(resolvedPath).digest('hex');\n\n const filename = externalId + path.extname(resolvedPath);\n\n options.externalComponentStyles.set(filename, resolvedPath);\n\n return filename;\n };\n}\n\nexport function augmentProgramWithVersioning(program: ts.Program): void {\n const baseGetSourceFiles = program.getSourceFiles;\n program.getSourceFiles = function (...parameters) {\n const files: readonly (ts.SourceFile & { version?: string })[] =\n baseGetSourceFiles(...parameters);\n\n for (const file of files) {\n file.version ??= createHash('sha256').update(file.text).digest('hex');\n }\n\n return files;\n };\n}\n\nexport function augmentHostWithCaching(\n host: ts.CompilerHost,\n cache: Map<string, ts.SourceFile>,\n): void {\n const baseGetSourceFile = host.getSourceFile;\n host.getSourceFile = function (\n fileName,\n languageVersion,\n onError,\n shouldCreateNewSourceFile,\n ...parameters\n ) {\n if (!shouldCreateNewSourceFile && cache.has(fileName)) {\n return cache.get(fileName);\n }\n\n const file = baseGetSourceFile.call(\n host,\n fileName,\n languageVersion,\n onError,\n true,\n ...parameters,\n );\n\n if (file) {\n cache.set(fileName, file);\n }\n\n return file;\n };\n}\n\nexport function mergeTransformers(\n first: ts.CustomTransformers,\n second: ts.CustomTransformers,\n): ts.CustomTransformers {\n const result: ts.CustomTransformers = {};\n\n if (first.before || second.before) {\n result.before = [...(first.before || []), ...(second.before || [])];\n }\n\n if (first.after || second.after) {\n result.after = [...(first.after || []), ...(second.after || [])];\n }\n\n if (first.afterDeclarations || second.afterDeclarations) {\n result.afterDeclarations = [\n ...(first.afterDeclarations || []),\n ...(second.afterDeclarations || []),\n ];\n }\n\n return result;\n}\n\nfunction hasStyleExtension(file: string): boolean {\n const extension = path.extname(file).toLowerCase();\n\n switch (extension) {\n case '.css':\n case '.scss':\n return true;\n default:\n return false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,65 +1,53 @@
|
|
|
1
|
-
import { resolve } from
|
|
2
|
-
import { normalizePath } from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return undefined;
|
|
50
|
-
},
|
|
51
|
-
load(id, options) {
|
|
52
|
-
if (options?.ssr && id.includes(ANGULAR_COMPONENT_PREFIX)) {
|
|
53
|
-
const requestUrl = new URL(id.slice(1), 'http://localhost');
|
|
54
|
-
const componentId = requestUrl.searchParams.get('c');
|
|
55
|
-
if (!componentId) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const result = fileEmitter(normalizePath(resolve(process.cwd(), decodeURIComponent(componentId).split('@')[0])));
|
|
59
|
-
return result?.hmrUpdateCode || '';
|
|
60
|
-
}
|
|
61
|
-
return;
|
|
62
|
-
},
|
|
63
|
-
};
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { normalizePath } from "vite";
|
|
3
|
+
//#region packages/vite-plugin-angular/src/lib/live-reload-plugin.ts
|
|
4
|
+
var ANGULAR_COMPONENT_PREFIX = "/@ng/component";
|
|
5
|
+
var FILE_PREFIX = "file:";
|
|
6
|
+
function liveReloadPlugin({ classNames, fileEmitter }) {
|
|
7
|
+
return {
|
|
8
|
+
name: "analogjs-live-reload-plugin",
|
|
9
|
+
apply: "serve",
|
|
10
|
+
configureServer(server) {
|
|
11
|
+
const angularComponentMiddleware = async (req, res, next) => {
|
|
12
|
+
if (req.url === void 0 || res.writableEnded) return;
|
|
13
|
+
if (!req.url.includes(ANGULAR_COMPONENT_PREFIX)) {
|
|
14
|
+
next();
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const componentId = new URL(req.url, "http://localhost").searchParams.get("c");
|
|
18
|
+
if (!componentId) {
|
|
19
|
+
res.statusCode = 400;
|
|
20
|
+
res.end();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const [fileId] = decodeURIComponent(componentId).split("@");
|
|
24
|
+
const resolvedId = normalizePath(resolve(process.cwd(), fileId));
|
|
25
|
+
if (!(!!server.moduleGraph.getModuleById(resolvedId)?.lastInvalidationTimestamp && classNames.get(resolvedId))) {
|
|
26
|
+
res.setHeader("Content-Type", "text/javascript");
|
|
27
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
28
|
+
res.end("");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const result = fileEmitter(resolvedId);
|
|
32
|
+
res.setHeader("Content-Type", "text/javascript");
|
|
33
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
34
|
+
res.end(`${result?.hmrUpdateCode || ""}`);
|
|
35
|
+
};
|
|
36
|
+
server.middlewares.use(angularComponentMiddleware);
|
|
37
|
+
},
|
|
38
|
+
resolveId(id, _importer, options) {
|
|
39
|
+
if (options?.ssr && id.startsWith(FILE_PREFIX) && id.includes(ANGULAR_COMPONENT_PREFIX)) return `\0${id}`;
|
|
40
|
+
},
|
|
41
|
+
load(id, options) {
|
|
42
|
+
if (options?.ssr && id.includes(ANGULAR_COMPONENT_PREFIX)) {
|
|
43
|
+
const componentId = new URL(id.slice(1), "http://localhost").searchParams.get("c");
|
|
44
|
+
if (!componentId) return;
|
|
45
|
+
return fileEmitter(normalizePath(resolve(process.cwd(), decodeURIComponent(componentId).split("@")[0])))?.hmrUpdateCode || "";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
64
49
|
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { liveReloadPlugin };
|
|
52
|
+
|
|
65
53
|
//# sourceMappingURL=live-reload-plugin.js.map
|