@nx/angular-rspack-compiler 23.2.0-beta.4 → 23.2.0-beta.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"setup-with-angular-compilation.d.ts","sourceRoot":"","sources":["../../src/compilation/setup-with-angular-compilation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAEL,kBAAkB,EAClB,eAAe,EAEhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAGL,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAE7B;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAED,wBAAsB,sCAAsC,CAC1D,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,EACrC,OAAO,EAAE,uBAAuB,EAChC,eAAe,CAAC,EAAE,eAAe,EACjC,kBAAkB,CAAC,EAAE,kBAAkB,EACvC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC;;;cA0DoB,MAAM;cAAQ,MAAM;;;;;;GA8GpE"}
1
+ {"version":3,"file":"setup-with-angular-compilation.d.ts","sourceRoot":"","sources":["../../src/compilation/setup-with-angular-compilation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAEL,kBAAkB,EAClB,eAAe,EAEhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAGL,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAE7B;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAED,wBAAsB,sCAAsC,CAC1D,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,EACrC,OAAO,EAAE,uBAAuB,EAChC,eAAe,CAAC,EAAE,eAAe,EACjC,kBAAkB,CAAC,EAAE,kBAAkB,EACvC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC;;;cA0DoB,MAAM;cAAQ,MAAM;;;;;;GA+GpE"}
@@ -104,8 +104,9 @@ async function setupCompilationWithAngularCompilation(config, options, sourceFil
104
104
  }
105
105
  // The compiler already tracks each source file's template and stylesheet
106
106
  // dependencies; re-key them like the emit cache so loaders can register
107
- // watch dependencies without re-parsing sources. AOT only: JIT compilations
108
- // do not report them and fall back to the URL resolvers.
107
+ // watch dependencies without re-parsing sources. JIT compilations do not
108
+ // report them, and neither does @angular/build 20 in any mode, so both fall
109
+ // back to the URL resolvers.
109
110
  let resourceDependencies;
110
111
  if (componentResourcesDependencies) {
111
112
  resourceDependencies = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"component-resolvers.d.ts","sourceRoot":"","sources":["../../src/utils/component-resolvers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAYH,qBAAa,iBAAiB;IAK5B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0C;IAEzE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CA6B1C;CACF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,YASxC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,YAO3C;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAG9B;IAEJ,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAa1C;CACF"}
1
+ {"version":3,"file":"component-resolvers.d.ts","sourceRoot":"","sources":["../../src/utils/component-resolvers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAWH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0C;IAEzE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAoB1C;CACF;AAgFD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAGnD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtD;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAG9B;IAEJ,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAa1C;CACF"}
@@ -27,29 +27,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
27
27
  exports.TemplateUrlsResolver = exports.StyleUrlsResolver = void 0;
28
28
  exports.getStyleUrls = getStyleUrls;
29
29
  exports.getTemplateUrls = getTemplateUrls;
30
+ const tslib_1 = require("tslib");
30
31
  const node_path_1 = require("node:path");
31
- const ts_morph_1 = require("ts-morph");
32
+ const ts = tslib_1.__importStar(require("typescript"));
32
33
  const path_1 = require("path");
33
- const utils_1 = require("./utils");
34
34
  class StyleUrlsResolver {
35
35
  constructor() {
36
- // These resolvers may be called multiple times during the same
37
- // compilation for the same files. Caching is required because these
38
- // resolvers use synchronous system calls to the filesystem, which can
39
- // degrade performance when running compilations for multiple files.
40
36
  this.styleUrlsCache = new Map();
41
37
  }
42
38
  resolve(code, id) {
43
- // Given the code is the following:
44
- // @Component({
45
- // styleUrls: [
46
- // './app.component.scss'
47
- // ]
48
- // })
49
- // The `matchedStyleUrls` would result in: `styleUrls: [\n './app.component.scss'\n ]`.
50
- const matchedStyleUrls = getStyleUrls(code)
51
- // for type narrowing
52
- .filter((v) => v !== undefined);
39
+ const matchedStyleUrls = getStyleUrls(code);
53
40
  const entry = this.styleUrlsCache.get(id);
54
41
  // We're using `matchedStyleUrls` as a key because the code may be changing continuously,
55
42
  // resulting in the resolver being called multiple times. While the code changes, the
@@ -67,19 +54,69 @@ class StyleUrlsResolver {
67
54
  }
68
55
  }
69
56
  exports.StyleUrlsResolver = StyleUrlsResolver;
57
+ let lastScan;
58
+ // These resolvers run only when the Angular compilation did not report the
59
+ // component's resource dependencies, so they follow @angular/build's JIT
60
+ // resource transformer: a resource becomes a module only when its URL is a
61
+ // plain string literal, and anything else names no file to watch. Empty is
62
+ // skipped for all three properties because it resolves to the component's own
63
+ // directory rather than a file; Angular skips it for `templateUrl` and
64
+ // `styleUrls` entries but not for `styleUrl`.
65
+ function collectUrl(urls, node) {
66
+ if (ts.isStringLiteralLike(node) && node.text) {
67
+ urls.push(node.text);
68
+ }
69
+ }
70
+ // Both resolvers run back to back on the same source in the rspack loader, so
71
+ // the last scan is memoized to parse each file once instead of twice.
72
+ function scanComponentResources(code) {
73
+ if (lastScan !== undefined && lastScan.code === code) {
74
+ return lastScan.resources;
75
+ }
76
+ const sourceFile = ts.createSourceFile('cmp.ts', code, ts.ScriptTarget.Latest,
77
+ // parent pointers are unused: every value below is read off the node itself
78
+ false, ts.ScriptKind.TS);
79
+ const styleUrl = [];
80
+ const styleUrls = [];
81
+ const templateUrl = [];
82
+ // Every property assignment in the file is considered, not just the ones in a
83
+ // @Component decorator: Angular identifies that decorator by resolving its
84
+ // symbol to @angular/core, which needs a type checker this parse has no
85
+ // program for.
86
+ const visit = (node) => {
87
+ if (ts.isPropertyAssignment(node) &&
88
+ // identifier and quoted keys name the same property, computed ones are
89
+ // dropped, matching how Angular reflects @Component metadata
90
+ (ts.isIdentifier(node.name) || ts.isStringLiteral(node.name))) {
91
+ const name = node.name.text;
92
+ if (name === 'styleUrl') {
93
+ collectUrl(styleUrl, node.initializer);
94
+ }
95
+ else if (name === 'templateUrl') {
96
+ collectUrl(templateUrl, node.initializer);
97
+ }
98
+ else if (name === 'styleUrls' &&
99
+ ts.isArrayLiteralExpression(node.initializer)) {
100
+ for (const element of node.initializer.elements) {
101
+ collectUrl(styleUrls, element);
102
+ }
103
+ }
104
+ }
105
+ ts.forEachChild(node, visit);
106
+ };
107
+ ts.forEachChild(sourceFile, visit);
108
+ const resources = { styleUrl, styleUrls, templateUrl };
109
+ lastScan = { code, resources };
110
+ return resources;
111
+ }
112
+ // the explicit return types keep the memoized `readonly string[]` arrays from
113
+ // being handed to callers unspread
70
114
  function getStyleUrls(code) {
71
- const project = new ts_morph_1.Project({ useInMemoryFileSystem: true });
72
- const sourceFile = project.createSourceFile('cmp.ts', code);
73
- const properties = sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.PropertyAssignment);
74
- const styleUrl = (0, utils_1.getTextByProperty)('styleUrl', properties);
75
- const styleUrls = (0, utils_1.getAllTextByProperty)('styleUrls', properties);
115
+ const { styleUrl, styleUrls } = scanComponentResources(code);
76
116
  return [...styleUrls, ...styleUrl];
77
117
  }
78
118
  function getTemplateUrls(code) {
79
- const project = new ts_morph_1.Project({ useInMemoryFileSystem: true });
80
- const sourceFile = project.createSourceFile('cmp.ts', code);
81
- const properties = sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.PropertyAssignment);
82
- return (0, utils_1.getTextByProperty)('templateUrl', properties);
119
+ return [...scanComponentResources(code).templateUrl];
83
120
  }
84
121
  class TemplateUrlsResolver {
85
122
  constructor() {
@@ -1,8 +1,4 @@
1
- import { PropertyAssignment } from 'ts-morph';
2
1
  export declare const isUsingWindows: () => boolean;
3
- export declare function getTextByProperty(name: string, properties: PropertyAssignment[]): string[];
4
- export declare function getAllTextByProperty(name: string, properties: PropertyAssignment[]): string[];
5
- export declare function normalizeQuotes(str?: string): string;
6
2
  export declare function isPresent(variable: string | undefined): variable is string;
7
3
  export declare function parseMaxWorkers(value: string | undefined): number | null;
8
4
  export declare const maxWorkers: () => number;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGtE,eAAO,MAAM,cAAc,eAA+B,CAAC;AAE3D,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,kBAAkB,EAAE,YAMjC;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,kBAAkB,EAAE,YAQjC;AAED,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,UAE3C;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,IAAI,MAAM,CAE1E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIxE;AAED,eAAO,MAAM,UAAU,cAKtB,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,eAA+B,CAAC;AAE3D,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,IAAI,MAAM,CAE1E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIxE;AAED,eAAO,MAAM,UAAU,cAKtB,CAAC"}
@@ -1,30 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.maxWorkers = exports.isUsingWindows = void 0;
4
- exports.getTextByProperty = getTextByProperty;
5
- exports.getAllTextByProperty = getAllTextByProperty;
6
- exports.normalizeQuotes = normalizeQuotes;
7
4
  exports.isPresent = isPresent;
8
5
  exports.parseMaxWorkers = parseMaxWorkers;
9
6
  const node_os_1 = require("node:os");
10
7
  const constants_1 = require("./constants");
11
8
  const isUsingWindows = () => (0, node_os_1.platform)() === 'win32';
12
9
  exports.isUsingWindows = isUsingWindows;
13
- function getTextByProperty(name, properties) {
14
- return properties
15
- .filter((property) => property.getName() === name)
16
- .map((property) => normalizeQuotes(property.getInitializer()?.getText()))
17
- .filter((url) => url !== undefined);
18
- }
19
- function getAllTextByProperty(name, properties) {
20
- return properties
21
- .filter((property) => property.getName() === name)
22
- .map((property) => property.getInitializer())
23
- .flatMap((array) => array.getElements().map((el) => normalizeQuotes(el.getText())));
24
- }
25
- function normalizeQuotes(str) {
26
- return str ? str.replace(/['"`]/g, '') : str;
27
- }
28
10
  function isPresent(variable) {
29
11
  return typeof variable === 'string' && variable.trim() !== '';
30
12
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nx/angular-rspack-compiler",
3
3
  "private": false,
4
- "version": "23.2.0-beta.4",
4
+ "version": "23.2.0-beta.5",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -42,10 +42,9 @@
42
42
  "dependencies": {
43
43
  "sass-embedded": "^1.97.2",
44
44
  "semver": "^7.6.3",
45
- "ts-morph": "^28.0.0",
46
45
  "tslib": "^2.3.0",
47
46
  "typescript": "~6.0.3",
48
- "@nx/devkit": "23.2.0-beta.4"
47
+ "@nx/devkit": "23.2.0-beta.5"
49
48
  },
50
49
  "devDependencies": {
51
50
  "jsonc-eslint-parser": "^2.4.0",