@analogjs/vite-plugin-angular 3.0.0-alpha.44 → 3.0.0-alpha.46

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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # @analogjs/vite-plugin-angular
2
2
 
3
+ [![Vite Plugin Registry](https://img.shields.io/badge/vite-plugin--registry-blue?logo=vite)](https://registry.vite.dev/plugin/@analogjs/vite-plugin-angular)
4
+
3
5
  A Vite plugin for building Angular applications
4
6
 
5
7
  ## Install
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/vite-plugin-angular",
3
- "version": "3.0.0-alpha.44",
3
+ "version": "3.0.0-alpha.46",
4
4
  "description": "Vite Plugin for Angular",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -33,8 +33,24 @@
33
33
  },
34
34
  "@angular/build": {
35
35
  "optional": true
36
+ },
37
+ "vite": {
38
+ "optional": true
36
39
  }
37
40
  },
41
+ "compatiblePackages": {
42
+ "vite": [
43
+ "^6.0.0",
44
+ "^7.0.0",
45
+ "^8.0.0"
46
+ ],
47
+ "rollup": [
48
+ "^4.0.0"
49
+ ],
50
+ "rolldown": [
51
+ "^1.0.0"
52
+ ]
53
+ },
38
54
  "dependencies": {
39
55
  "es-toolkit": "^1.45.1",
40
56
  "magic-string": "^0.30.21",
@@ -1,6 +1,5 @@
1
1
  import { debugStyles } from "./utils/debug.js";
2
2
  import { isTailwindReferenceError } from "./utils/tailwind-reference.js";
3
- import { shouldPreprocessTestCss } from "./utils/virtual-resources.js";
4
3
  import { preprocessCSS } from "vite";
5
4
  import { createHash } from "node:crypto";
6
5
  //#region packages/vite-plugin-angular/src/lib/angular-jit-plugin.ts
@@ -20,8 +19,6 @@ function jitPlugin({ inlineStylesExtension }) {
20
19
  const styleIdHash = createHash("sha256").update(styleId).digest("hex").slice(0, 16);
21
20
  const decodedStyles = Buffer.from(decodeURIComponent(styleId), "base64").toString();
22
21
  let styles = "";
23
- const inlineStyleId = `${styleIdHash}.${inlineStylesExtension}`;
24
- if (!shouldPreprocessTestCss(config, inlineStyleId)) return `export default \`\``;
25
22
  try {
26
23
  styles = (await preprocessCSS(decodedStyles, `${styleIdHash}.${inlineStylesExtension}?direct`, config))?.code;
27
24
  } catch (e) {
@@ -1 +1 @@
1
- {"version":3,"file":"angular-jit-plugin.js","names":[],"sources":["../../../src/lib/angular-jit-plugin.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { Plugin, ResolvedConfig, preprocessCSS } from 'vite';\nimport { debugStyles } from './utils/debug.js';\nimport { isTailwindReferenceError } from './utils/tailwind-reference.js';\n\nimport { shouldPreprocessTestCss } from './utils/virtual-resources.js';\n\nexport function jitPlugin({\n inlineStylesExtension,\n}: {\n inlineStylesExtension: string;\n}): Plugin {\n let config: ResolvedConfig;\n\n return {\n name: '@analogjs/vite-plugin-angular-jit',\n configResolved(_config) {\n config = _config;\n },\n resolveId(id: string) {\n if (id.startsWith('virtual:angular')) {\n return `\\0${id}`;\n }\n\n return;\n },\n async load(id: string) {\n if (id.includes('virtual:angular:jit:style:inline;')) {\n const styleId = id.split('style:inline;')[1];\n // styleId may exceed 255 bytes of base64-encoded content, limit to 16\n const styleIdHash = createHash('sha256')\n .update(styleId)\n .digest('hex')\n .slice(0, 16);\n\n const decodedStyles = Buffer.from(\n decodeURIComponent(styleId),\n 'base64',\n ).toString();\n\n let styles: string | undefined = '';\n\n // In tests, mirror Vitest's `test.css` rules — defaults to no\n // preprocessing (matches Vite's CSS pipeline behavior). Inline\n // component styles have no real file path to match include/exclude\n // patterns against, so only `test.css: true` opts them in. (#2297)\n const inlineStyleId = `${styleIdHash}.${inlineStylesExtension}`;\n if (!shouldPreprocessTestCss(config, inlineStyleId)) {\n return `export default \\`\\``;\n }\n\n try {\n const compiled = await preprocessCSS(\n decodedStyles,\n `${styleIdHash}.${inlineStylesExtension}?direct`,\n config,\n );\n styles = compiled?.code;\n } catch (e) {\n if (isTailwindReferenceError(e)) {\n throw e;\n }\n const errorMessage = e instanceof Error ? e.message : String(e);\n debugStyles('jit css compilation error', {\n styleIdHash,\n error: errorMessage,\n });\n console.warn(\n '[@analogjs/vite-plugin-angular]: Failed to preprocess inline JIT stylesheet %s. Returning an empty stylesheet instead. %s',\n styleIdHash,\n errorMessage,\n );\n }\n\n return `export default \\`${styles}\\``;\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;;;;AAOA,SAAgB,UAAU,EACxB,yBAGS;CACT,IAAI;AAEJ,QAAO;EACL,MAAM;EACN,eAAe,SAAS;AACtB,YAAS;;EAEX,UAAU,IAAY;AACpB,OAAI,GAAG,WAAW,kBAAkB,CAClC,QAAO,KAAK;;EAKhB,MAAM,KAAK,IAAY;AACrB,OAAI,GAAG,SAAS,oCAAoC,EAAE;IACpD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC;IAE1C,MAAM,cAAc,WAAW,SAAS,CACrC,OAAO,QAAQ,CACf,OAAO,MAAM,CACb,MAAM,GAAG,GAAG;IAEf,MAAM,gBAAgB,OAAO,KAC3B,mBAAmB,QAAQ,EAC3B,SACD,CAAC,UAAU;IAEZ,IAAI,SAA6B;IAMjC,MAAM,gBAAgB,GAAG,YAAY,GAAG;AACxC,QAAI,CAAC,wBAAwB,QAAQ,cAAc,CACjD,QAAO;AAGT,QAAI;AAMF,eALiB,MAAM,cACrB,eACA,GAAG,YAAY,GAAG,sBAAsB,UACxC,OACD,GACkB;aACZ,GAAG;AACV,SAAI,yBAAyB,EAAE,CAC7B,OAAM;KAER,MAAM,eAAe,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AAC/D,iBAAY,6BAA6B;MACvC;MACA,OAAO;MACR,CAAC;AACF,aAAQ,KACN,6HACA,aACA,aACD;;AAGH,WAAO,oBAAoB,OAAO;;;EAKvC"}
1
+ {"version":3,"file":"angular-jit-plugin.js","names":[],"sources":["../../../src/lib/angular-jit-plugin.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { Plugin, ResolvedConfig, preprocessCSS } from 'vite';\nimport { debugStyles } from './utils/debug.js';\nimport { isTailwindReferenceError } from './utils/tailwind-reference.js';\n\nexport function jitPlugin({\n inlineStylesExtension,\n}: {\n inlineStylesExtension: string;\n}): Plugin {\n let config: ResolvedConfig;\n\n return {\n name: '@analogjs/vite-plugin-angular-jit',\n configResolved(_config) {\n config = _config;\n },\n resolveId(id: string) {\n if (id.startsWith('virtual:angular')) {\n return `\\0${id}`;\n }\n\n return;\n },\n async load(id: string) {\n if (id.includes('virtual:angular:jit:style:inline;')) {\n const styleId = id.split('style:inline;')[1];\n // styleId may exceed 255 bytes of base64-encoded content, limit to 16\n const styleIdHash = createHash('sha256')\n .update(styleId)\n .digest('hex')\n .slice(0, 16);\n\n const decodedStyles = Buffer.from(\n decodeURIComponent(styleId),\n 'base64',\n ).toString();\n\n let styles: string | undefined = '';\n\n try {\n const compiled = await preprocessCSS(\n decodedStyles,\n `${styleIdHash}.${inlineStylesExtension}?direct`,\n config,\n );\n styles = compiled?.code;\n } catch (e) {\n if (isTailwindReferenceError(e)) {\n throw e;\n }\n const errorMessage = e instanceof Error ? e.message : String(e);\n debugStyles('jit css compilation error', {\n styleIdHash,\n error: errorMessage,\n });\n console.warn(\n '[@analogjs/vite-plugin-angular]: Failed to preprocess inline JIT stylesheet %s. Returning an empty stylesheet instead. %s',\n styleIdHash,\n errorMessage,\n );\n }\n\n return `export default \\`${styles}\\``;\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;;;AAKA,SAAgB,UAAU,EACxB,yBAGS;CACT,IAAI;AAEJ,QAAO;EACL,MAAM;EACN,eAAe,SAAS;AACtB,YAAS;;EAEX,UAAU,IAAY;AACpB,OAAI,GAAG,WAAW,kBAAkB,CAClC,QAAO,KAAK;;EAKhB,MAAM,KAAK,IAAY;AACrB,OAAI,GAAG,SAAS,oCAAoC,EAAE;IACpD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC;IAE1C,MAAM,cAAc,WAAW,SAAS,CACrC,OAAO,QAAQ,CACf,OAAO,MAAM,CACb,MAAM,GAAG,GAAG;IAEf,MAAM,gBAAgB,OAAO,KAC3B,mBAAmB,QAAQ,EAC3B,SACD,CAAC,UAAU;IAEZ,IAAI,SAA6B;AAEjC,QAAI;AAMF,eALiB,MAAM,cACrB,eACA,GAAG,YAAY,GAAG,sBAAsB,UACxC,OACD,GACkB;aACZ,GAAG;AACV,SAAI,yBAAyB,EAAE,CAC7B,OAAM;KAER,MAAM,eAAe,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AAC/D,iBAAY,6BAA6B;MACvC;MACA,OAAO;MACR,CAAC;AACF,aAAQ,KACN,6HACA,aACA,aACD;;AAGH,WAAO,oBAAoB,OAAO;;;EAKvC"}
@@ -2,7 +2,6 @@ import { angularFullVersion, cjt, sourceFileCache } from "./utils/devkit.js";
2
2
  import { getJsTransformConfigKey, isRolldown } from "./utils/rolldown.js";
3
3
  import { buildOptimizerPlugin } from "./angular-build-optimizer-plugin.js";
4
4
  import { activateDeferredDebug, applyDebugOption, debugCompiler, debugCompilerV, debugEmit, debugEmitV, debugHmr, debugHmrV, debugStyles, debugStylesV } from "./utils/debug.js";
5
- import { toVirtualRawId, toVirtualStyleId } from "./utils/virtual-ids.js";
6
5
  import { jitPlugin } from "./angular-jit-plugin.js";
7
6
  import { createCompilerPlugin, createRolldownCompilerPlugin } from "./compiler-plugin.js";
8
7
  import { StyleUrlsResolver, TemplateUrlsResolver, getAngularComponentMetadata } from "./component-resolvers.js";
@@ -11,9 +10,12 @@ import { augmentHostWithCaching, augmentHostWithResources, augmentProgramWithVer
11
10
  import { TS_EXT_REGEX, createTsConfigGetter, getTsConfigPath } from "./utils/plugin-config.js";
12
11
  import { TsconfigResolver } from "./utils/tsconfig-resolver.js";
13
12
  import { configureStylePipelineRegistry } from "./style-pipeline.js";
14
- import { describeStylesheetContent, injectViteIgnoreForHmrMetadata, isIgnoredHmrFile, isTestWatchMode, refreshStylesheetRegistryForFile } from "./utils/compilation-shared.js";
13
+ import { describeStylesheetContent, injectViteIgnoreForHmrMetadata, isIgnoredHmrFile, isTestWatchMode } from "./utils/compilation-shared.js";
15
14
  import { compilationAPIPlugin } from "./compilation-api/compilation-api-plugin.js";
16
15
  import "./compilation-api/index.js";
16
+ import { toVirtualRawId } from "./utils/virtual-ids.js";
17
+ import { loadVirtualRawModule, rewriteHtmlRawImport } from "./utils/virtual-resources.js";
18
+ import { markStylePathSafe } from "./utils/safe-module-paths.js";
17
19
  import { fastCompilePlugin } from "./fast-compile-plugin.js";
18
20
  import { removeActiveGraphMetadata, removeStyleOwnerMetadata, templateClassBindingGuardPlugin } from "./template-class-binding-guard-plugin.js";
19
21
  import { buildStylePreprocessor, tailwindReferencePlugin, validateTailwindConfig } from "./tailwind-plugin.js";
@@ -26,8 +28,8 @@ import { nxFolderPlugin } from "./nx-folder-plugin.js";
26
28
  import { replaceFiles } from "./plugins/file-replacements.plugin.js";
27
29
  import { routerPlugin } from "./router-plugin.js";
28
30
  import { union } from "es-toolkit";
29
- import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
30
- import { basename, dirname, join, relative, resolve } from "node:path";
31
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
32
+ import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
31
33
  import * as compilerCli from "@angular/compiler-cli";
32
34
  import { createRequire } from "node:module";
33
35
  import { defaultClientConditions, normalizePath, preprocessCSS } from "vite";
@@ -351,32 +353,6 @@ function angular(options) {
351
353
  if (/\.(html|htm|css|less|sass|scss)$/.test(ctx.file)) {
352
354
  debugHmr("resource file changed", { file: ctx.file });
353
355
  fileTransformMap.delete(ctx.file.split("?")[0]);
354
- if (/\.(css|less|sass|scss)$/.test(ctx.file)) refreshStylesheetRegistryForFile(ctx.file, stylesheetRegistry, pluginOptions.stylePreprocessor);
355
- if (/\.(css|less|sass|scss)$/.test(ctx.file) && existsSync(ctx.file)) try {
356
- const rawResource = readFileSync(ctx.file, "utf-8");
357
- debugHmrV("resource source snapshot", {
358
- file: ctx.file,
359
- mtimeMs: safeStatMtimeMs(ctx.file),
360
- ...describeStylesheetContent(rawResource)
361
- });
362
- } catch (error) {
363
- debugHmrV("resource source snapshot failed", {
364
- file: ctx.file,
365
- error: String(error)
366
- });
367
- }
368
- const fileModules = await getModulesForChangedFile(ctx.server, ctx.file, ctx.modules, stylesheetRegistry);
369
- debugHmrV("resource modules resolved", {
370
- file: ctx.file,
371
- eventModuleCount: ctx.modules.length,
372
- fileModuleCount: fileModules.length,
373
- modules: fileModules.map((mod) => ({
374
- id: mod.id,
375
- file: mod.file,
376
- type: mod.type,
377
- url: mod.url
378
- }))
379
- });
380
356
  /**
381
357
  * Check to see if this was a direct request
382
358
  * for an external resource (styles, html).
@@ -591,7 +567,24 @@ function angular(options) {
591
567
  classNames.clear();
592
568
  return ctx.modules;
593
569
  },
594
- resolveId(id) {
570
+ resolveId(id, importer) {
571
+ if (id.startsWith("virtual:@analogjs/vite-plugin-angular:raw:")) return `\0${id}`;
572
+ if (jit && id.startsWith("angular:jit:")) {
573
+ const filePath = normalizePath(resolve(dirname(importer), id.split(";")[1]));
574
+ if (id.includes(":style")) {
575
+ markStylePathSafe(resolvedConfig, filePath);
576
+ return filePath + "?inline";
577
+ }
578
+ return toVirtualRawId(filePath);
579
+ }
580
+ const rawRewrite = rewriteHtmlRawImport(id, importer);
581
+ if (rawRewrite) return rawRewrite;
582
+ if (/\.(css|scss|sass|less)\?inline$/.test(id) && importer) {
583
+ const filePath = id.split("?")[0];
584
+ const resolved = isAbsolute(filePath) ? normalizePath(filePath) : normalizePath(resolve(dirname(importer), filePath));
585
+ markStylePathSafe(resolvedConfig, resolved);
586
+ return resolved + "?inline";
587
+ }
595
588
  if (isComponentStyleSheet(id)) {
596
589
  const filename = getFilenameFromPath(id);
597
590
  if (stylesheetRegistry?.hasServed(filename)) {
@@ -614,6 +607,9 @@ function angular(options) {
614
607
  }
615
608
  },
616
609
  async load(id) {
610
+ const rawModule = await loadVirtualRawModule(this, id);
611
+ if (rawModule !== void 0) return rawModule;
612
+ if (/\.(css|scss|sass|less)\?inline$/.test(id)) markStylePathSafe(resolvedConfig, id.split("?")[0]);
617
613
  if (isComponentStyleSheet(id)) {
618
614
  const filename = getFilenameFromPath(id);
619
615
  const componentStyles = stylesheetRegistry?.getServedContent(filename);
@@ -718,7 +714,8 @@ function angular(options) {
718
714
  });
719
715
  styleUrls.forEach((styleUrlSet) => {
720
716
  const [styleFile, resolvedStyleUrl] = styleUrlSet.split("|");
721
- data = data.replace(`angular:jit:style:file;${styleFile}`, toVirtualStyleId(resolvedStyleUrl));
717
+ markStylePathSafe(resolvedConfig, resolvedStyleUrl);
718
+ data = data.replace(`angular:jit:style:file;${styleFile}`, resolvedStyleUrl + "?inline");
722
719
  });
723
720
  }
724
721
  if (data.includes("HmrLoad")) {
@@ -784,7 +781,6 @@ function angular(options) {
784
781
  virtualModulesPlugin({ jit }),
785
782
  templateClassBindingGuardPlugin(guardContext),
786
783
  pluginOptions.hasTailwindCss && tailwindReferencePlugin({ tailwindCss: pluginOptions.tailwindCss }),
787
- angularPlugin(),
788
784
  pluginOptions.liveReload && liveReloadPlugin({
789
785
  classNames,
790
786
  fileEmitter
@@ -972,48 +968,6 @@ function createFsWatcherCacheInvalidator(invalidateFsCaches, invalidateTsconfigC
972
968
  await performCompilation();
973
969
  };
974
970
  }
975
- /**
976
- * Returns every live Vite module that can legitimately represent a changed
977
- * Angular resource file.
978
- *
979
- * For normal files, `getModulesByFile()` is enough. For Angular component
980
- * stylesheets, it is not: the browser often holds virtual hashed requests
981
- * (`/abc123.css?direct&ngcomp=...` and `/abc123.css?ngcomp=...`) that are no
982
- * longer discoverable from the original source path alone. We therefore merge:
983
- * - watcher event modules
984
- * - module-graph modules by source file
985
- * - registry-tracked live request ids resolved back through the module graph
986
- */
987
- async function getModulesForChangedFile(server, file, eventModules = [], stylesheetRegistry) {
988
- const normalizedFile = normalizePath(file.split("?")[0]);
989
- const modules = /* @__PURE__ */ new Map();
990
- for (const mod of eventModules) if (mod.id) modules.set(mod.id, mod);
991
- server.moduleGraph.getModulesByFile(normalizedFile)?.forEach((mod) => {
992
- if (mod.id) modules.set(mod.id, mod);
993
- });
994
- const stylesheetRequestIds = stylesheetRegistry?.getRequestIdsForSource(normalizedFile) ?? [];
995
- const requestIdHits = [];
996
- for (const requestId of stylesheetRequestIds) {
997
- const candidates = [requestId, requestId.startsWith("/") ? requestId : `/${requestId}`];
998
- for (const candidate of candidates) {
999
- const mod = await server.moduleGraph.getModuleByUrl(candidate) ?? server.moduleGraph.getModuleById(candidate);
1000
- requestIdHits.push({
1001
- requestId,
1002
- candidate,
1003
- via: mod?.url === candidate ? "url" : "id",
1004
- moduleId: mod?.id
1005
- });
1006
- if (mod?.id) modules.set(mod.id, mod);
1007
- }
1008
- }
1009
- debugHmrV("getModulesForChangedFile registry lookup", {
1010
- file: normalizedFile,
1011
- stylesheetRequestIds,
1012
- requestIdHits,
1013
- resolvedModuleIds: [...modules.keys()]
1014
- });
1015
- return [...modules.values()];
1016
- }
1017
971
  function isModuleForChangedResource(mod, changedFile, stylesheetRegistry) {
1018
972
  const normalizedChangedFile = normalizePath(changedFile.split("?")[0]);
1019
973
  if (normalizePath((mod.file ?? "").split("?")[0]) === normalizedChangedFile) return true;
@@ -1021,13 +975,6 @@ function isModuleForChangedResource(mod, changedFile, stylesheetRegistry) {
1021
975
  const requestPath = getFilenameFromPath(mod.id);
1022
976
  return normalizePath((stylesheetRegistry?.resolveExternalSource(requestPath) ?? stylesheetRegistry?.resolveExternalSource(requestPath.replace(/^\//, "")) ?? "").split("?")[0]) === normalizedChangedFile;
1023
977
  }
1024
- function safeStatMtimeMs(file) {
1025
- try {
1026
- return statSync(file).mtimeMs;
1027
- } catch {
1028
- return;
1029
- }
1030
- }
1031
978
  function diagnoseComponentStylesheetPipeline(changedFile, directModule, stylesheetRegistry, wrapperModules, stylePreprocessor) {
1032
979
  const normalizedFile = normalizePath(changedFile.split("?")[0]);
1033
980
  const sourceExists = existsSync(normalizedFile);