@analogjs/vite-plugin-angular 3.0.0-alpha.88 → 3.0.0-alpha.89

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.
Files changed (32) hide show
  1. package/package.json +1 -1
  2. package/src/lib/angular-build-optimizer-plugin.d.ts +4 -0
  3. package/src/lib/angular-build-optimizer-plugin.js +49 -26
  4. package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
  5. package/src/lib/angular-jit-plugin.js +4 -0
  6. package/src/lib/angular-jit-plugin.js.map +1 -1
  7. package/src/lib/angular-vite-plugin.js +47 -7
  8. package/src/lib/angular-vite-plugin.js.map +1 -1
  9. package/src/lib/compilation-api/compilation-api-plugin.js +2 -2
  10. package/src/lib/compilation-api/compilation-api-plugin.js.map +1 -1
  11. package/src/lib/compiler/compile.js +1 -1
  12. package/src/lib/compiler/compile.js.map +1 -1
  13. package/src/lib/compiler-plugin.js +3 -3
  14. package/src/lib/compiler-plugin.js.map +1 -1
  15. package/src/lib/encapsulation-plugin.d.ts +6 -1
  16. package/src/lib/encapsulation-plugin.js +24 -9
  17. package/src/lib/encapsulation-plugin.js.map +1 -1
  18. package/src/lib/fast-compile-plugin.d.ts +10 -0
  19. package/src/lib/fast-compile-plugin.js +21 -7
  20. package/src/lib/fast-compile-plugin.js.map +1 -1
  21. package/src/lib/router-plugin.js +2 -2
  22. package/src/lib/router-plugin.js.map +1 -1
  23. package/src/lib/utils/css-preprocessor-workers.d.ts +6 -0
  24. package/src/lib/utils/css-preprocessor-workers.js +29 -0
  25. package/src/lib/utils/css-preprocessor-workers.js.map +1 -0
  26. package/src/lib/utils/devkit.d.ts +9 -1
  27. package/src/lib/utils/devkit.js +39 -1
  28. package/src/lib/utils/devkit.js.map +1 -1
  29. package/src/lib/utils/transform-cache.d.ts +1 -1
  30. package/src/lib/utils/transform-cache.js.map +1 -1
  31. package/src/lib/utils/tsconfig-resolver.js +6 -4
  32. package/src/lib/utils/tsconfig-resolver.js.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/vite-plugin-angular",
3
- "version": "3.0.0-alpha.88",
3
+ "version": "3.0.0-alpha.89",
4
4
  "description": "Vite Plugin for Angular",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -3,3 +3,7 @@ export declare function buildOptimizerPlugin({ jit }: {
3
3
  supportedBrowsers: string[];
4
4
  jit: boolean;
5
5
  }): Plugin;
6
+ export declare function extractInlineSourceMap(code: string, id: string): {
7
+ code: string;
8
+ map: string | null;
9
+ };
@@ -1,11 +1,24 @@
1
- import { jt } from "./utils/devkit.js";
1
+ import { JavaScriptTransformer } from "./utils/devkit.js";
2
2
  import { isProdMode } from "./utils/plugin-config.js";
3
- import { getJsTransformConfigKey } from "./utils/rolldown.js";
4
3
  //#region packages/vite-plugin-angular/src/lib/angular-build-optimizer-plugin.ts
5
4
  function buildOptimizerPlugin({ jit }) {
6
- let javascriptTransformer;
5
+ const transformers = /* @__PURE__ */ new Map();
7
6
  let isProd = false;
7
+ let isWatch = false;
8
8
  let preserveVendorMaps = false;
9
+ function getTransformer(envName = "default") {
10
+ let transformer = transformers.get(envName);
11
+ if (!transformer) {
12
+ transformer = new JavaScriptTransformer({
13
+ sourcemap: preserveVendorMaps,
14
+ thirdPartySourcemaps: preserveVendorMaps,
15
+ advancedOptimizations: isProd,
16
+ jit: true
17
+ }, 1);
18
+ transformers.set(envName, transformer);
19
+ }
20
+ return transformer;
21
+ }
9
22
  return {
10
23
  name: "@analogjs/vite-plugin-angular-optimizer",
11
24
  apply(_config, env) {
@@ -13,33 +26,19 @@ function buildOptimizerPlugin({ jit }) {
13
26
  },
14
27
  config(userConfig) {
15
28
  isProd = isProdMode(userConfig.mode);
16
- javascriptTransformer ??= new jt({
17
- sourcemap: false,
18
- thirdPartySourcemaps: false,
19
- advancedOptimizations: isProd,
20
- jit: true
21
- }, 1);
22
- const jsTransformConfigKey = getJsTransformConfigKey();
23
- return {
24
- define: isProd ? {
25
- ngJitMode: "false",
26
- ngI18nClosureMode: "false",
27
- ngDevMode: "false",
28
- ngServerMode: `${!!userConfig.build?.ssr}`
29
- } : {},
30
- [jsTransformConfigKey]: { define: isProd ? {
31
- ngDevMode: "false",
32
- ngJitMode: "false",
33
- ngI18nClosureMode: "false",
34
- ngServerMode: `${!!userConfig.build?.ssr}`
35
- } : void 0 }
36
- };
29
+ return { define: isProd ? {
30
+ ngJitMode: "false",
31
+ ngI18nClosureMode: "false",
32
+ ngDevMode: "false",
33
+ ngServerMode: `${!!userConfig.build?.ssr}`
34
+ } : {} };
37
35
  },
38
36
  configEnvironment(_name, config) {
39
37
  if (isProd && config.consumer === "server") return { define: { ngServerMode: "true" } };
40
38
  },
41
39
  configResolved(config) {
42
40
  preserveVendorMaps = !!config.build.sourcemap;
41
+ isWatch = config.command === "serve" || !!config.build?.watch;
43
42
  },
44
43
  transform: {
45
44
  filter: { id: /\.[cm]?js(?:\?|$)/ },
@@ -50,12 +49,36 @@ function buildOptimizerPlugin({ jit }) {
50
49
  map: preserveVendorMaps ? null : { mappings: "" }
51
50
  };
52
51
  const sideEffects = jit && cleanId.includes("@angular/compiler") ? true : false;
53
- const result = await javascriptTransformer.transformData(cleanId, code, false, sideEffects);
54
- return { code: Buffer.from(result).toString() };
52
+ const result = await getTransformer(this.environment?.name ?? "default").transformData(cleanId, code, false, sideEffects);
53
+ const transformed = Buffer.from(result).toString();
54
+ return preserveVendorMaps ? extractInlineSourceMap(transformed, cleanId) : {
55
+ code: transformed,
56
+ map: { mappings: "" }
57
+ };
58
+ }
59
+ },
60
+ async closeBundle() {
61
+ if (isWatch) return;
62
+ const envName = this.environment?.name ?? "default";
63
+ const transformer = transformers.get(envName);
64
+ if (transformer) {
65
+ transformers.delete(envName);
66
+ await transformer.close();
55
67
  }
56
68
  }
57
69
  };
58
70
  }
71
+ function extractInlineSourceMap(code, id) {
72
+ const sourceMapMatch = code.match(/\n?\/\/# sourceMappingURL=data:application\/json(?:;charset=[^;,]+)?;base64,([A-Za-z0-9+/=]+)\s*$/);
73
+ if (!sourceMapMatch || sourceMapMatch.index === void 0) return {
74
+ code,
75
+ map: null
76
+ };
77
+ return {
78
+ code: code.slice(0, sourceMapMatch.index),
79
+ map: Buffer.from(sourceMapMatch[1], "base64").toString()
80
+ };
81
+ }
59
82
  //#endregion
60
83
  export { buildOptimizerPlugin };
61
84
 
@@ -1 +1 @@
1
- {"version":3,"file":"angular-build-optimizer-plugin.js","names":[],"sources":["../../../src/lib/angular-build-optimizer-plugin.ts"],"sourcesContent":["import type { Plugin, UserConfig } from 'vite';\nimport { JavaScriptTransformer } from './utils/devkit.js';\nimport { isProdMode } from './utils/plugin-config.js';\nimport { getJsTransformConfigKey } from './utils/rolldown.js';\n\nexport function buildOptimizerPlugin({\n jit,\n}: {\n supportedBrowsers: string[];\n jit: boolean;\n}): Plugin {\n let javascriptTransformer: InstanceType<typeof JavaScriptTransformer>;\n let isProd = false;\n let preserveVendorMaps = false;\n\n return {\n name: '@analogjs/vite-plugin-angular-optimizer',\n // Normally build-only. Astro's Cloudflare integration (`@astrojs/cloudflare`)\n // transforms SSR modules through a serve-style `workerd` runner *during*\n // `astro build`; an `apply: 'build'` plugin is excluded from that pipeline,\n // so the Angular linker never runs on the worker's partially-compiled\n // packages and they fall back to the JIT compiler. Also apply under a\n // production `NODE_ENV` (which `astro build` sets) so the linker runs in\n // that runner too. Regular Analog dev servers run with a development\n // `NODE_ENV`, so their behavior is unchanged.\n apply(_config, env) {\n return (\n env.command === 'build' || process.env['NODE_ENV'] === 'production'\n );\n },\n config(userConfig) {\n isProd = isProdMode(userConfig.mode);\n // Advanced optimizations paired with dev-mode defines would strip\n // dev-only code the debug API needs, so both key off `isProd`.\n javascriptTransformer ??= new JavaScriptTransformer(\n {\n sourcemap: false,\n thirdPartySourcemaps: false,\n advancedOptimizations: isProd,\n jit: true,\n },\n 1,\n );\n const jsTransformConfigKey = getJsTransformConfigKey();\n\n return {\n define: isProd\n ? {\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ngDevMode: 'false',\n ngServerMode: `${!!userConfig.build?.ssr}`,\n }\n : {},\n [jsTransformConfigKey]: {\n define: isProd\n ? {\n ngDevMode: 'false',\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ngServerMode: `${!!userConfig.build?.ssr}`,\n }\n : undefined,\n },\n } as UserConfig;\n },\n // The top-level define keys `ngServerMode` off the legacy `build.ssr`\n // flag. Environment API builds run the server through an environment\n // with `consumer: 'server'` while `build.ssr` stays unset, so give that\n // environment its own value; otherwise the guard compiles to `false`\n // and browser-only hydration features run during SSR.\n configEnvironment(_name, config) {\n if (isProd && config.consumer === 'server') {\n return { define: { ngServerMode: 'true' } };\n }\n return undefined;\n },\n configResolved(config) {\n preserveVendorMaps = !!config.build.sourcemap;\n },\n transform: {\n filter: {\n // Allow an optional `?query` after the extension. Some environments\n // (e.g. Cloudflare's `workerd`, used by Astro's Cloudflare integration)\n // reference optimized deps with a `?v=<hash>` suffix, e.g.\n // `.../fesm2022/_platform_location-chunk.mjs?v=a786a9ff`. A `$`-anchored\n // extension match skips those, so the Angular linker never runs and the\n // partially-compiled package falls back to the JIT compiler at runtime.\n id: /\\.[cm]?js(?:\\?|$)/,\n },\n async handler(code, id) {\n // Strip the `?query` so the fesm check and the transformer see a real\n // filename rather than `foo.mjs?v=<hash>`.\n const cleanId = id.split('?')[0];\n const angularPackage = /fesm20/.test(cleanId);\n\n if (!angularPackage) {\n // `{ mappings: '' }` declares zero segments, dropping the module's own\n // map from the chain; `null` keeps it. Removing `sourceMappingURL` is\n // what makes that map unreachable, so it only runs when discarding.\n return {\n code:\n isProd && !preserveVendorMaps\n ? code.replace(/^\\/\\/# sourceMappingURL=[^\\r\\n]*/gm, '')\n : code,\n map: preserveVendorMaps ? null : { mappings: '' },\n };\n }\n\n const sideEffects =\n jit && cleanId.includes('@angular/compiler') ? true : false;\n const result: Uint8Array = await javascriptTransformer.transformData(\n cleanId,\n code,\n false,\n sideEffects,\n );\n\n return {\n code: Buffer.from(result).toString(),\n };\n },\n },\n };\n}\n"],"mappings":";;;;AAKA,SAAgB,qBAAqB,EACnC,OAIS;CACT,IAAI;CACJ,IAAI,SAAS;CACb,IAAI,qBAAqB;AAEzB,QAAO;EACL,MAAM;EASN,MAAM,SAAS,KAAK;AAClB,UACE,IAAI,YAAY,WAAA,QAAA,IAAA,aAAuC;;EAG3D,OAAO,YAAY;AACjB,YAAS,WAAW,WAAW,KAAK;AAGpC,6BAA0B,IAAI,GAC5B;IACE,WAAW;IACX,sBAAsB;IACtB,uBAAuB;IACvB,KAAK;IACN,EACD,EACD;GACD,MAAM,uBAAuB,yBAAyB;AAEtD,UAAO;IACL,QAAQ,SACJ;KACE,WAAW;KACX,mBAAmB;KACnB,WAAW;KACX,cAAc,GAAG,CAAC,CAAC,WAAW,OAAO;KACtC,GACD,EAAE;KACL,uBAAuB,EACtB,QAAQ,SACJ;KACE,WAAW;KACX,WAAW;KACX,mBAAmB;KACnB,cAAc,GAAG,CAAC,CAAC,WAAW,OAAO;KACtC,GACD,KAAA,GACL;IACF;;EAOH,kBAAkB,OAAO,QAAQ;AAC/B,OAAI,UAAU,OAAO,aAAa,SAChC,QAAO,EAAE,QAAQ,EAAE,cAAc,QAAQ,EAAE;;EAI/C,eAAe,QAAQ;AACrB,wBAAqB,CAAC,CAAC,OAAO,MAAM;;EAEtC,WAAW;GACT,QAAQ,EAON,IAAI,qBACL;GACD,MAAM,QAAQ,MAAM,IAAI;IAGtB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAG9B,QAAI,CAFmB,SAAS,KAAK,QAAQ,CAM3C,QAAO;KACL,MACE,UAAU,CAAC,qBACP,KAAK,QAAQ,sCAAsC,GAAG,GACtD;KACN,KAAK,qBAAqB,OAAO,EAAE,UAAU,IAAI;KAClD;IAGH,MAAM,cACJ,OAAO,QAAQ,SAAS,oBAAoB,GAAG,OAAO;IACxD,MAAM,SAAqB,MAAM,sBAAsB,cACrD,SACA,MACA,OACA,YACD;AAED,WAAO,EACL,MAAM,OAAO,KAAK,OAAO,CAAC,UAAU,EACrC;;GAEJ;EACF"}
1
+ {"version":3,"file":"angular-build-optimizer-plugin.js","names":[],"sources":["../../../src/lib/angular-build-optimizer-plugin.ts"],"sourcesContent":["import type { Plugin, UserConfig } from 'vite';\nimport { JavaScriptTransformer } from './utils/devkit.js';\nimport { isProdMode } from './utils/plugin-config.js';\n\nexport function buildOptimizerPlugin({\n jit,\n}: {\n supportedBrowsers: string[];\n jit: boolean;\n}): Plugin {\n const transformers = new Map<\n string,\n InstanceType<typeof JavaScriptTransformer>\n >();\n let isProd = false;\n let isWatch = false;\n let preserveVendorMaps = false;\n\n function getTransformer(envName = 'default') {\n let transformer = transformers.get(envName);\n if (!transformer) {\n transformer = new JavaScriptTransformer(\n {\n sourcemap: preserveVendorMaps,\n thirdPartySourcemaps: preserveVendorMaps,\n advancedOptimizations: isProd,\n jit: true,\n },\n 1,\n );\n transformers.set(envName, transformer);\n }\n return transformer;\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-optimizer',\n // Normally build-only. Astro's Cloudflare integration (`@astrojs/cloudflare`)\n // transforms SSR modules through a serve-style `workerd` runner *during*\n // `astro build`; an `apply: 'build'` plugin is excluded from that pipeline,\n // so the Angular linker never runs on the worker's partially-compiled\n // packages and they fall back to the JIT compiler. Also apply under a\n // production `NODE_ENV` (which `astro build` sets) so the linker runs in\n // that runner too. Regular Analog dev servers run with a development\n // `NODE_ENV`, so their behavior is unchanged.\n apply(_config, env) {\n return (\n env.command === 'build' || process.env['NODE_ENV'] === 'production'\n );\n },\n config(userConfig) {\n isProd = isProdMode(userConfig.mode);\n // Advanced optimizations paired with dev-mode defines would strip\n // dev-only code the debug API needs, so both key off `isProd`.\n return {\n define: isProd\n ? {\n ngJitMode: 'false',\n ngI18nClosureMode: 'false',\n ngDevMode: 'false',\n ngServerMode: `${!!userConfig.build?.ssr}`,\n }\n : {},\n } as UserConfig;\n },\n // The top-level define keys `ngServerMode` off the legacy `build.ssr`\n // flag. Environment API builds run the server through an environment\n // with `consumer: 'server'` while `build.ssr` stays unset, so give that\n // environment its own value; otherwise the guard compiles to `false`\n // and browser-only hydration features run during SSR.\n configEnvironment(_name, config) {\n if (isProd && config.consumer === 'server') {\n return { define: { ngServerMode: 'true' } };\n }\n return undefined;\n },\n configResolved(config) {\n preserveVendorMaps = !!config.build.sourcemap;\n isWatch = config.command === 'serve' || !!config.build?.watch;\n },\n transform: {\n filter: {\n // Allow an optional `?query` after the extension. Some environments\n // (e.g. Cloudflare's `workerd`, used by Astro's Cloudflare integration)\n // reference optimized deps with a `?v=<hash>` suffix, e.g.\n // `.../fesm2022/_platform_location-chunk.mjs?v=a786a9ff`. A `$`-anchored\n // extension match skips those, so the Angular linker never runs and the\n // partially-compiled package falls back to the JIT compiler at runtime.\n id: /\\.[cm]?js(?:\\?|$)/,\n },\n async handler(code, id) {\n // Strip the `?query` so the fesm check and the transformer see a real\n // filename rather than `foo.mjs?v=<hash>`.\n const cleanId = id.split('?')[0];\n const angularPackage = /fesm20/.test(cleanId);\n\n if (!angularPackage) {\n // `{ mappings: '' }` declares zero segments, dropping the module's own\n // map from the chain; `null` keeps it. Removing `sourceMappingURL` is\n // what makes that map unreachable, so it only runs when discarding.\n return {\n code:\n isProd && !preserveVendorMaps\n ? code.replace(/^\\/\\/# sourceMappingURL=[^\\r\\n]*/gm, '')\n : code,\n map: preserveVendorMaps ? null : { mappings: '' },\n };\n }\n\n const sideEffects =\n jit && cleanId.includes('@angular/compiler') ? true : false;\n const envName = this.environment?.name ?? 'default';\n const transformer = getTransformer(envName);\n const result: Uint8Array = await transformer.transformData(\n cleanId,\n code,\n false,\n sideEffects,\n );\n\n const transformed = Buffer.from(result).toString();\n return preserveVendorMaps\n ? extractInlineSourceMap(transformed, cleanId)\n : { code: transformed, map: { mappings: '' } };\n },\n },\n async closeBundle() {\n if (isWatch) {\n return;\n }\n const envName = this.environment?.name ?? 'default';\n const transformer = transformers.get(envName);\n if (transformer) {\n transformers.delete(envName);\n await transformer.close();\n }\n },\n };\n}\n\nexport function extractInlineSourceMap(\n code: string,\n id: string,\n): { code: string; map: string | null } {\n const sourceMapMatch = code.match(\n /\\n?\\/\\/# sourceMappingURL=data:application\\/json(?:;charset=[^;,]+)?;base64,([A-Za-z0-9+/=]+)\\s*$/,\n );\n if (!sourceMapMatch || sourceMapMatch.index === undefined) {\n return {\n code,\n map: null,\n };\n }\n return {\n code: code.slice(0, sourceMapMatch.index),\n map: Buffer.from(sourceMapMatch[1]!, 'base64').toString(),\n };\n}\n"],"mappings":";;;AAIA,SAAgB,qBAAqB,EACnC,OAIS;CACT,MAAM,+BAAe,IAAI,KAGtB;CACH,IAAI,SAAS;CACb,IAAI,UAAU;CACd,IAAI,qBAAqB;CAEzB,SAAS,eAAe,UAAU,WAAW;EAC3C,IAAI,cAAc,aAAa,IAAI,QAAQ;AAC3C,MAAI,CAAC,aAAa;AAChB,iBAAc,IAAI,sBAChB;IACE,WAAW;IACX,sBAAsB;IACtB,uBAAuB;IACvB,KAAK;IACN,EACD,EACD;AACD,gBAAa,IAAI,SAAS,YAAY;;AAExC,SAAO;;AAGT,QAAO;EACL,MAAM;EASN,MAAM,SAAS,KAAK;AAClB,UACE,IAAI,YAAY,WAAA,QAAA,IAAA,aAAuC;;EAG3D,OAAO,YAAY;AACjB,YAAS,WAAW,WAAW,KAAK;AAGpC,UAAO,EACL,QAAQ,SACJ;IACE,WAAW;IACX,mBAAmB;IACnB,WAAW;IACX,cAAc,GAAG,CAAC,CAAC,WAAW,OAAO;IACtC,GACD,EAAE,EACP;;EAOH,kBAAkB,OAAO,QAAQ;AAC/B,OAAI,UAAU,OAAO,aAAa,SAChC,QAAO,EAAE,QAAQ,EAAE,cAAc,QAAQ,EAAE;;EAI/C,eAAe,QAAQ;AACrB,wBAAqB,CAAC,CAAC,OAAO,MAAM;AACpC,aAAU,OAAO,YAAY,WAAW,CAAC,CAAC,OAAO,OAAO;;EAE1D,WAAW;GACT,QAAQ,EAON,IAAI,qBACL;GACD,MAAM,QAAQ,MAAM,IAAI;IAGtB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAG9B,QAAI,CAFmB,SAAS,KAAK,QAAQ,CAM3C,QAAO;KACL,MACE,UAAU,CAAC,qBACP,KAAK,QAAQ,sCAAsC,GAAG,GACtD;KACN,KAAK,qBAAqB,OAAO,EAAE,UAAU,IAAI;KAClD;IAGH,MAAM,cACJ,OAAO,QAAQ,SAAS,oBAAoB,GAAG,OAAO;IAGxD,MAAM,SAAqB,MADP,eADJ,KAAK,aAAa,QAAQ,UACC,CACE,cAC3C,SACA,MACA,OACA,YACD;IAED,MAAM,cAAc,OAAO,KAAK,OAAO,CAAC,UAAU;AAClD,WAAO,qBACH,uBAAuB,aAAa,QAAQ,GAC5C;KAAE,MAAM;KAAa,KAAK,EAAE,UAAU,IAAI;KAAE;;GAEnD;EACD,MAAM,cAAc;AAClB,OAAI,QACF;GAEF,MAAM,UAAU,KAAK,aAAa,QAAQ;GAC1C,MAAM,cAAc,aAAa,IAAI,QAAQ;AAC7C,OAAI,aAAa;AACf,iBAAa,OAAO,QAAQ;AAC5B,UAAM,YAAY,OAAO;;;EAG9B;;AAGH,SAAgB,uBACd,MACA,IACsC;CACtC,MAAM,iBAAiB,KAAK,MAC1B,oGACD;AACD,KAAI,CAAC,kBAAkB,eAAe,UAAU,KAAA,EAC9C,QAAO;EACL;EACA,KAAK;EACN;AAEH,QAAO;EACL,MAAM,KAAK,MAAM,GAAG,eAAe,MAAM;EACzC,KAAK,OAAO,KAAK,eAAe,IAAK,SAAS,CAAC,UAAU;EAC1D"}
@@ -2,6 +2,7 @@ import { debugStyles } from "./utils/debug.js";
2
2
  import { preprocessStylesheet } from "./stylesheet-registry.js";
3
3
  import { discoverAnalogIntegrations } from "./analog-plugin-interop.js";
4
4
  import { getJitInlineStyles } from "./utils/jit-inline-styles.js";
5
+ import { releaseCssPreprocessorWorkers } from "./utils/css-preprocessor-workers.js";
5
6
  import { preprocessCSS } from "vite";
6
7
  //#region packages/vite-plugin-angular/src/lib/angular-jit-plugin.ts
7
8
  function jitPlugin({ inlineStylesExtension }) {
@@ -42,6 +43,9 @@ function jitPlugin({ inlineStylesExtension }) {
42
43
  }
43
44
  return `export default \`${styles}\``;
44
45
  }
46
+ },
47
+ closeBundle() {
48
+ if (!this.meta?.watchMode) releaseCssPreprocessorWorkers();
45
49
  }
46
50
  };
47
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"angular-jit-plugin.js","names":[],"sources":["../../../src/lib/angular-jit-plugin.ts"],"sourcesContent":["import { Plugin, ResolvedConfig, preprocessCSS } from 'vite';\nimport {\n JIT_INLINE_STYLE_PREFIX,\n getJitInlineStyles,\n} from './utils/jit-inline-styles.js';\nimport { debugStyles } from './utils/debug.js';\nimport { discoverAnalogIntegrations } from './analog-plugin-interop.js';\nimport { preprocessStylesheet } from './stylesheet-registry.js';\nimport type { StylePreprocessor } from './style-preprocessor.js';\n\nexport function jitPlugin({\n inlineStylesExtension,\n}: {\n inlineStylesExtension: string;\n}): Plugin {\n let config: ResolvedConfig;\n let stylePreprocessor: StylePreprocessor | undefined;\n\n return {\n name: '@analogjs/vite-plugin-angular-jit',\n configResolved(_config) {\n config = _config;\n },\n async buildStart() {\n stylePreprocessor = (await discoverAnalogIntegrations(config))\n .stylePreprocessor;\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(JIT_INLINE_STYLE_PREFIX)) {\n const styleIdHash = id.split('style:inline;')[1];\n const encodedStyles = getJitInlineStyles(styleIdHash);\n\n if (encodedStyles === undefined) {\n return;\n }\n\n const decodedStyles = Buffer.from(\n decodeURIComponent(encodedStyles),\n 'base64',\n ).toString();\n const filename = `${styleIdHash}.${inlineStylesExtension}`;\n const preprocessed = preprocessStylesheet(\n decodedStyles,\n filename,\n stylePreprocessor,\n { filename, inline: true },\n );\n\n let styles: string | undefined = '';\n\n try {\n const compiled = await preprocessCSS(\n preprocessed,\n `${filename}?direct`,\n config,\n );\n styles = compiled?.code;\n } catch (e) {\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":";;;;;;AAUA,SAAgB,UAAU,EACxB,yBAGS;CACT,IAAI;CACJ,IAAI;AAEJ,QAAO;EACL,MAAM;EACN,eAAe,SAAS;AACtB,YAAS;;EAEX,MAAM,aAAa;AACjB,wBAAqB,MAAM,2BAA2B,OAAO,EAC1D;;EAEL,UAAU,IAAY;AACpB,OAAI,GAAG,WAAW,kBAAkB,CAClC,QAAO,KAAK;;EAKhB,MAAM,KAAK,IAAY;AACrB,OAAI,GAAG,SAAA,oCAAiC,EAAE;IACxC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC;IAC9C,MAAM,gBAAgB,mBAAmB,YAAY;AAErD,QAAI,kBAAkB,KAAA,EACpB;IAGF,MAAM,gBAAgB,OAAO,KAC3B,mBAAmB,cAAc,EACjC,SACD,CAAC,UAAU;IACZ,MAAM,WAAW,GAAG,YAAY,GAAG;IACnC,MAAM,eAAe,qBACnB,eACA,UACA,mBACA;KAAE;KAAU,QAAQ;KAAM,CAC3B;IAED,IAAI,SAA6B;AAEjC,QAAI;AAMF,eALiB,MAAM,cACrB,cACA,GAAG,SAAS,UACZ,OACD,GACkB;aACZ,GAAG;KACV,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 { Plugin, ResolvedConfig, preprocessCSS } from 'vite';\nimport {\n JIT_INLINE_STYLE_PREFIX,\n getJitInlineStyles,\n} from './utils/jit-inline-styles.js';\nimport { debugStyles } from './utils/debug.js';\nimport { discoverAnalogIntegrations } from './analog-plugin-interop.js';\nimport { preprocessStylesheet } from './stylesheet-registry.js';\nimport type { StylePreprocessor } from './style-preprocessor.js';\nimport { releaseCssPreprocessorWorkers } from './utils/css-preprocessor-workers.js';\n\nexport function jitPlugin({\n inlineStylesExtension,\n}: {\n inlineStylesExtension: string;\n}): Plugin {\n let config: ResolvedConfig;\n let stylePreprocessor: StylePreprocessor | undefined;\n\n return {\n name: '@analogjs/vite-plugin-angular-jit',\n configResolved(_config) {\n config = _config;\n },\n async buildStart() {\n stylePreprocessor = (await discoverAnalogIntegrations(config))\n .stylePreprocessor;\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(JIT_INLINE_STYLE_PREFIX)) {\n const styleIdHash = id.split('style:inline;')[1];\n const encodedStyles = getJitInlineStyles(styleIdHash);\n\n if (encodedStyles === undefined) {\n return;\n }\n\n const decodedStyles = Buffer.from(\n decodeURIComponent(encodedStyles),\n 'base64',\n ).toString();\n const filename = `${styleIdHash}.${inlineStylesExtension}`;\n const preprocessed = preprocessStylesheet(\n decodedStyles,\n filename,\n stylePreprocessor,\n { filename, inline: true },\n );\n\n let styles: string | undefined = '';\n\n try {\n const compiled = await preprocessCSS(\n preprocessed,\n `${filename}?direct`,\n config,\n );\n styles = compiled?.code;\n } catch (e) {\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 closeBundle() {\n if (!this.meta?.watchMode) {\n releaseCssPreprocessorWorkers();\n }\n },\n };\n}\n"],"mappings":";;;;;;;AAWA,SAAgB,UAAU,EACxB,yBAGS;CACT,IAAI;CACJ,IAAI;AAEJ,QAAO;EACL,MAAM;EACN,eAAe,SAAS;AACtB,YAAS;;EAEX,MAAM,aAAa;AACjB,wBAAqB,MAAM,2BAA2B,OAAO,EAC1D;;EAEL,UAAU,IAAY;AACpB,OAAI,GAAG,WAAW,kBAAkB,CAClC,QAAO,KAAK;;EAKhB,MAAM,KAAK,IAAY;AACrB,OAAI,GAAG,SAAA,oCAAiC,EAAE;IACxC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC;IAC9C,MAAM,gBAAgB,mBAAmB,YAAY;AAErD,QAAI,kBAAkB,KAAA,EACpB;IAGF,MAAM,gBAAgB,OAAO,KAC3B,mBAAmB,cAAc,EACjC,SACD,CAAC,UAAU;IACZ,MAAM,WAAW,GAAG,YAAY,GAAG;IACnC,MAAM,eAAe,qBACnB,eACA,UACA,mBACA;KAAE;KAAU,QAAQ;KAAM,CAC3B;IAED,IAAI,SAA6B;AAEjC,QAAI;AAMF,eALiB,MAAM,cACrB,cACA,GAAG,SAAS,UACZ,OACD,GACkB;aACZ,GAAG;KACV,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;;;EAKtC,cAAc;AACZ,OAAI,CAAC,KAAK,MAAM,UACd,gCAA+B;;EAGpC"}
@@ -10,6 +10,7 @@ import { describeStylesheetContent, injectViteIgnoreForHmrMetadata, isIgnoredHmr
10
10
  import { angularVitestPlugins } from "./angular-vitest-plugin.js";
11
11
  import { buildOptimizerPlugin } from "./angular-build-optimizer-plugin.js";
12
12
  import { toJitInlineStyleId } from "./utils/jit-inline-styles.js";
13
+ import { releaseCssPreprocessorWorkers } from "./utils/css-preprocessor-workers.js";
13
14
  import { jitPlugin } from "./angular-jit-plugin.js";
14
15
  import { liveReloadPlugin } from "./live-reload-plugin.js";
15
16
  import { toVirtualRawId } from "./utils/virtual-ids.js";
@@ -115,6 +116,11 @@ function angular(options) {
115
116
  }
116
117
  let stylesheetRegistry;
117
118
  const sourceFileCache$1 = new sourceFileCache();
119
+ const tsSourceFileCache = /* @__PURE__ */ new Map();
120
+ function invalidateSourceFiles(files) {
121
+ for (const file of files) tsSourceFileCache.delete(normalizePath(file));
122
+ sourceFileCache$1.invalidate(files);
123
+ }
118
124
  const isVitestVscode = !!process.env["VITEST_VSCODE"];
119
125
  const isStackBlitz = !!process.versions["webcontainer"];
120
126
  const isAstroIntegration = process.env["ANALOG_ASTRO"] === "true";
@@ -247,6 +253,10 @@ function angular(options) {
247
253
  const invalidateCompilationOnFsChange = createFsWatcherCacheInvalidator(invalidateFsCaches, invalidateTsconfigCaches, () => performCompilation(resolvedConfig));
248
254
  server.watcher.on("add", invalidateCompilationOnFsChange);
249
255
  server.watcher.on("unlink", (file) => {
256
+ const id = normalizePath(file);
257
+ outputFiles.delete(id);
258
+ tsSourceFileCache.delete(id);
259
+ sourceFileCache$1.invalidate(new Set([id]));
250
260
  evictDeletedFileMetadata(file, {
251
261
  classNamesMap: classNames,
252
262
  fileTransformMap
@@ -259,12 +269,29 @@ function angular(options) {
259
269
  },
260
270
  async buildStart() {
261
271
  if (!isVitestVscode) {
262
- pendingCompilation = performCompilation(resolvedConfig);
272
+ pendingCompilation = performCompilation(this.environment?.config ?? resolvedConfig);
263
273
  await pendingCompilation;
264
274
  pendingCompilation = null;
265
275
  initialCompilation = true;
266
276
  }
267
277
  },
278
+ buildEnd() {
279
+ if (watchMode) return;
280
+ nextProgram = void 0;
281
+ cachedHost = void 0;
282
+ cachedHostKey = void 0;
283
+ outputFile = void 0;
284
+ outputFiles.clear();
285
+ fileTransformMap.clear();
286
+ tsSourceFileCache.clear();
287
+ sourceFileCache$1.clear();
288
+ sourceFileCache$1.modifiedFiles.clear();
289
+ sourceFileCache$1.babelFileCache?.clear();
290
+ sourceFileCache$1.typeScriptFileCache?.clear();
291
+ sourceFileCache$1.referencedFiles = void 0;
292
+ tsconfigResolver.invalidateAll();
293
+ releaseCssPreprocessorWorkers();
294
+ },
268
295
  async handleHotUpdate(ctx) {
269
296
  if (isIgnoredHmrFile(ctx.file)) {
270
297
  debugHmr("ignored file change", { file: ctx.file });
@@ -592,13 +619,13 @@ function angular(options) {
592
619
  */
593
620
  if (isTest) {
594
621
  if (isVitestVscode && !initialCompilation) {
595
- pendingCompilation = performCompilation(resolvedConfig);
622
+ pendingCompilation = performCompilation(this.environment?.config ?? resolvedConfig);
596
623
  initialCompilation = true;
597
624
  }
598
625
  const tsMod = viteServer?.moduleGraph.getModuleById(id);
599
626
  if (tsMod) {
600
627
  const invalidated = tsMod.lastInvalidationTimestamp;
601
- if (testWatchMode && invalidated) pendingCompilation = performCompilation(resolvedConfig, [id]);
628
+ if (testWatchMode && invalidated) pendingCompilation = performCompilation(this.environment?.config ?? resolvedConfig, [id]);
602
629
  }
603
630
  }
604
631
  const hasComponent = code.includes("@Component");
@@ -670,7 +697,7 @@ function angular(options) {
670
697
  if (typescriptResult.map) data = data.replace(/\s*\/\/# sourceMappingURL=[^\r\n]*\s*$/, "");
671
698
  return {
672
699
  code: data,
673
- map: typescriptResult.map ?? null
700
+ map: typescriptResult.map ? normalizeSourceMapSources(typescriptResult.map, id) : null
674
701
  };
675
702
  }
676
703
  },
@@ -679,9 +706,22 @@ function angular(options) {
679
706
  mkdirSync(declarationFileDir, { recursive: true });
680
707
  writeFileSync(declarationPath, data, "utf-8");
681
708
  });
709
+ declarationFiles.length = 0;
710
+ if (!watchMode) releaseCssPreprocessorWorkers();
682
711
  }
683
712
  };
684
713
  }
714
+ function normalizeSourceMapSources(map, id) {
715
+ const sourceMap = JSON.parse(map);
716
+ const sourceDirectory = dirname(id);
717
+ const sourceRoot = sourceMap.sourceRoot ?? "";
718
+ sourceMap.sources = sourceMap.sources?.map((source) => {
719
+ if (isAbsolute(source) || /^[a-z][a-z\d+.-]*:/i.test(source)) return normalizePath(source);
720
+ return normalizePath(resolve(sourceDirectory, sourceRoot, source));
721
+ });
722
+ delete sourceMap.sourceRoot;
723
+ return JSON.stringify(sourceMap);
724
+ }
685
725
  const compilationPlugin = pluginOptions.fastCompile ? fastCompilePlugin({
686
726
  tsconfigGetter: pluginOptions.tsconfigGetter,
687
727
  workspaceRoot: pluginOptions.workspaceRoot,
@@ -745,9 +785,9 @@ function angular(options) {
745
785
  * It should not be called concurrently. Use `performCompilation` which wraps this method in a lock to ensure only one compilation runs at a time.
746
786
  */
747
787
  async function _doPerformCompilation(config, ids) {
788
+ if (!jit) styleTransform = (code, filename) => preprocessCSS(code, filename, config);
748
789
  const isProd = config.mode === "production";
749
- const modifiedFiles = new Set(ids ?? []);
750
- sourceFileCache$1.invalidate(modifiedFiles);
790
+ invalidateSourceFiles(new Set(ids ?? []));
751
791
  if (ids?.length) for (const id of ids || []) fileTransformMap.delete(id);
752
792
  const resolvedTsConfigPath = resolveTsConfigPath();
753
793
  const cached = tsconfigResolver.getCachedTsconfigOptions(resolvedTsConfigPath, config);
@@ -793,7 +833,7 @@ function angular(options) {
793
833
  });
794
834
  cachedHost = host;
795
835
  cachedHostKey = hostKey;
796
- if (watchMode) augmentHostWithCaching(host, sourceFileCache$1);
836
+ if (watchMode) augmentHostWithCaching(host, tsSourceFileCache);
797
837
  }
798
838
  if (!jit) {
799
839
  const externalizeStyles = !!tsCompilerOptions["externalRuntimeStyles"];