@nx/angular-rspack-compiler 23.2.0-beta.1 → 23.2.0-beta.11

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 (35) hide show
  1. package/README.md +2 -2
  2. package/dist/compilation/build-and-analyze.d.ts +13 -1
  3. package/dist/compilation/build-and-analyze.d.ts.map +1 -1
  4. package/dist/compilation/build-and-analyze.js +17 -17
  5. package/dist/compilation/setup-compilation.d.ts +24 -0
  6. package/dist/compilation/setup-compilation.d.ts.map +1 -1
  7. package/dist/compilation/setup-compilation.js +62 -5
  8. package/dist/compilation/setup-with-angular-compilation.d.ts +14 -0
  9. package/dist/compilation/setup-with-angular-compilation.d.ts.map +1 -1
  10. package/dist/compilation/setup-with-angular-compilation.js +111 -15
  11. package/dist/models/index.d.ts +3 -2
  12. package/dist/models/index.d.ts.map +1 -1
  13. package/dist/models/index.js +4 -2
  14. package/dist/utils/component-resolvers.d.ts.map +1 -1
  15. package/dist/utils/component-resolvers.js +62 -25
  16. package/dist/utils/index.d.ts +2 -0
  17. package/dist/utils/index.d.ts.map +1 -1
  18. package/dist/utils/index.js +2 -0
  19. package/dist/utils/javascript-transformer-cache.d.ts +18 -0
  20. package/dist/utils/javascript-transformer-cache.d.ts.map +1 -0
  21. package/dist/utils/javascript-transformer-cache.js +31 -0
  22. package/dist/utils/regex-filters.d.ts +2 -0
  23. package/dist/utils/regex-filters.d.ts.map +1 -1
  24. package/dist/utils/regex-filters.js +3 -1
  25. package/dist/utils/source-file-cache.d.ts +43 -2
  26. package/dist/utils/source-file-cache.d.ts.map +1 -1
  27. package/dist/utils/source-file-cache.js +36 -4
  28. package/dist/utils/typescript-compiler-options.d.ts +41 -0
  29. package/dist/utils/typescript-compiler-options.d.ts.map +1 -0
  30. package/dist/utils/typescript-compiler-options.js +63 -0
  31. package/dist/utils/utils.d.ts +0 -4
  32. package/dist/utils/utils.d.ts.map +1 -1
  33. package/dist/utils/utils.js +0 -18
  34. package/package.json +2 -3
  35. package/patch/patch-angular-build.js +2 -3
package/README.md CHANGED
@@ -7,9 +7,9 @@
7
7
 
8
8
  <div style="text-align: center;">
9
9
 
10
- [![License](https://img.shields.io/npm/l/@nx/workspace.svg?style=flat-square)]()
10
+ [![License](https://img.shields.io/npm/l/@nx/workspace.svg?style=flat-square)](<>)
11
11
  [![NPM Version](https://badge.fury.io/js/nx.svg)](https://www.npmjs.com/package/nx)
12
- [![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)]()
12
+ [![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](<>)
13
13
  [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
14
14
  [![Join us on the Official Nx Discord Server](https://img.shields.io/discord/1143497901675401286?label=discord)](https://go.nx.dev/community)
15
15
  [![Nx Sandboxing](https://staging.nx.app/workspaces/62d013ea0852fe0a2df74438/sandbox-badge.svg)](https://nx.dev/docs/features/ci-features/sandboxing)
@@ -1,4 +1,16 @@
1
1
  import { JavaScriptTransformer } from '@angular/build/private';
2
2
  import { AngularCompilation } from '../models';
3
- export declare function buildAndAnalyze(angularCompilation: AngularCompilation, typescriptFileCache: Map<string, string | Uint8Array>, javascriptTransformer: JavaScriptTransformer): Promise<void>;
3
+ import { type TransformedSource } from '../utils/source-file-cache';
4
+ /**
5
+ * Emits the affected files of the Angular compilation into the given file
6
+ * cache as raw, untransformed text. The Rspack loaders in `@nx/angular-rspack`
7
+ * run the JavaScript transformer on entries on demand and replace them in
8
+ * place, so only files the bundler actually requests pay the transformation
9
+ * cost, matching the on-demand transformation in `@angular/build`'s esbuild
10
+ * compiler plugin.
11
+ *
12
+ * @param javascriptTransformer Unused. Kept for signature compatibility; the
13
+ * transformer now runs in the loaders.
14
+ */
15
+ export declare function buildAndAnalyze(angularCompilation: AngularCompilation, typescriptFileCache: Map<string, string | TransformedSource>, javascriptTransformer: JavaScriptTransformer): Promise<void>;
4
16
  //# sourceMappingURL=build-and-analyze.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-and-analyze.d.ts","sourceRoot":"","sources":["../../src/compilation/build-and-analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAK/C,wBAAsB,eAAe,CACnC,kBAAkB,EAAE,kBAAkB,EACtC,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,EACrD,qBAAqB,EAAE,qBAAqB,iBA8B7C"}
1
+ {"version":3,"file":"build-and-analyze.d.ts","sourceRoot":"","sources":["../../src/compilation/build-and-analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,kBAAkB,EAAE,kBAAkB,EACtC,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAAC,EAC5D,qBAAqB,EAAE,qBAAqB,iBAgB7C"}
@@ -1,26 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildAndAnalyze = buildAndAnalyze;
4
- const path_1 = require("path");
5
4
  const assert_supported_versions_1 = require("../utils/assert-supported-versions");
6
- const JS_TS_FILE_PATTERN = /\.[cm]?[jt]sx?$/;
5
+ const source_file_cache_1 = require("../utils/source-file-cache");
6
+ /**
7
+ * Emits the affected files of the Angular compilation into the given file
8
+ * cache as raw, untransformed text. The Rspack loaders in `@nx/angular-rspack`
9
+ * run the JavaScript transformer on entries on demand and replace them in
10
+ * place, so only files the bundler actually requests pay the transformation
11
+ * cost, matching the on-demand transformation in `@angular/build`'s esbuild
12
+ * compiler plugin.
13
+ *
14
+ * @param javascriptTransformer Unused. Kept for signature compatibility; the
15
+ * transformer now runs in the loaders.
16
+ */
7
17
  async function buildAndAnalyze(angularCompilation, typescriptFileCache, javascriptTransformer) {
8
18
  (0, assert_supported_versions_1.assertSupportedAngularRspackCompilerVersions)();
9
19
  for (const { filename, contents, } of await angularCompilation.emitAffectedFiles()) {
10
- const normalizedFilename = (0, path_1.normalize)(filename.replace(/^[A-Z]:/, ''));
11
- // Skip JavaScript transformation for non-JS/TS files (JSON, CSS, etc.)
12
- // Let Rspack handle these through its native module rules
13
- if (!JS_TS_FILE_PATTERN.test(normalizedFilename)) {
14
- const text = typeof contents === 'string'
15
- ? contents
16
- : Buffer.from(contents).toString();
17
- typescriptFileCache.set(normalizedFilename, text);
18
- continue;
19
- }
20
- await javascriptTransformer
21
- .transformData(normalizedFilename, contents, true, false)
22
- .then((contents) => {
23
- typescriptFileCache.set(normalizedFilename, Buffer.from(contents).toString());
24
- });
20
+ const text = typeof contents === 'string'
21
+ ? contents
22
+ : Buffer.from(contents).toString();
23
+ // Setting the raw emit also evicts any stale transformed entry.
24
+ typescriptFileCache.set((0, source_file_cache_1.toTypeScriptFileCacheKey)(filename), text);
25
25
  }
26
26
  }
@@ -8,6 +8,14 @@ export interface StylesheetTransformResult {
8
8
  path: string;
9
9
  text: string;
10
10
  }>;
11
+ /** Bundle metadata listing the files that went into the stylesheet. */
12
+ metafile?: {
13
+ outputs: Record<string, {
14
+ inputs: Record<string, {
15
+ bytesInOutput: number;
16
+ }>;
17
+ }>;
18
+ };
11
19
  }
12
20
  export interface SetupCompilationOptions {
13
21
  root: string;
@@ -19,12 +27,28 @@ export interface SetupCompilationOptions {
19
27
  hasServer?: boolean;
20
28
  includePaths?: string[];
21
29
  sass?: Sass;
30
+ watch?: boolean;
31
+ sourceMap?: boolean;
32
+ preserveSymlinks?: boolean;
33
+ customConditions?: string[];
22
34
  }
23
35
  export declare const DEFAULT_NG_COMPILER_OPTIONS: ts.CompilerOptions;
36
+ /**
37
+ * Reads the project's TypeScript configuration with the Angular compiler
38
+ * defaults applied and creates (or reuses) the shared component stylesheet
39
+ * bundler. TypeScript sourcemaps are emitted inline and only when
40
+ * `options.sourceMap` is enabled. Targets below ES2022 are raised (see
41
+ * `applyEs2022TargetDefaults`), unsupported `module` values are set to
42
+ * ES2022, and partial compilation mode is forced to full, each with a
43
+ * warning in the returned `setupWarnings`. Combining `isolatedModules` with
44
+ * `emitDecoratorMetadata` is also warned about, without forcing either
45
+ * option.
46
+ */
24
47
  export declare function setupCompilation(config: Pick<RsbuildConfig, 'mode' | 'source'>, options: SetupCompilationOptions): Promise<{
25
48
  rootNames: readonly string[];
26
49
  compilerOptions: ts.CompilerOptions;
27
50
  componentStylesheetBundler: ComponentStylesheetBundler;
51
+ setupWarnings: string[];
28
52
  }>;
29
53
  /**
30
54
  * Dispose the shared component stylesheet bundler and reset the singleton.
@@ -1 +1 @@
1
- {"version":3,"file":"setup-compilation.d.ts","sourceRoot":"","sources":["../../src/compilation/setup-compilation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAG5E,OAAO,EACL,0BAA0B,EAI3B,MAAM,wBAAwB,CAAC;AAKhC,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,gBAAgB,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACzC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,eAAO,MAAM,2BAA2B,EAAE,EAAE,CAAC,eAc5C,CAAC;AAKF,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,CAAC,EAC9C,OAAO,EAAE,uBAAuB;;;;GAyEjC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC,CAMvE;AAED,wBAAgB,cAAc,CAC5B,0BAA0B,EAAE,0BAA0B,YAG5C,MAAM,kBACE,MAAM,mBACL,MAAM,KACtB,OAAO,CAAC,yBAAyB,CAAC,CAmCtC"}
1
+ {"version":3,"file":"setup-compilation.d.ts","sourceRoot":"","sources":["../../src/compilation/setup-compilation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAI5E,OAAO,EACL,0BAA0B,EAK3B,MAAM,wBAAwB,CAAC;AAIhC,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,uEAAuE;IACvE,QAAQ,CAAC,EAAE;QACT,OAAO,EAAE,MAAM,CACb,MAAM,EACN;YAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;gBAAE,aAAa,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CACtD,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,gBAAgB,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACzC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,eAAO,MAAM,2BAA2B,EAAE,EAAE,CAAC,eAa5C,CAAC;AAKF;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,CAAC,EAC9C,OAAO,EAAE,uBAAuB;;;;;GAsIjC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC,CAMvE;AAED,wBAAgB,cAAc,CAC5B,0BAA0B,EAAE,0BAA0B,YAG5C,MAAM,kBACE,MAAM,mBACL,MAAM,KACtB,OAAO,CAAC,yBAAyB,CAAC,CAmCtC"}
@@ -4,16 +4,17 @@ exports.DEFAULT_NG_COMPILER_OPTIONS = void 0;
4
4
  exports.setupCompilation = setupCompilation;
5
5
  exports.disposeComponentStylesheetBundler = disposeComponentStylesheetBundler;
6
6
  exports.styleTransform = styleTransform;
7
+ const tslib_1 = require("tslib");
8
+ const ts = tslib_1.__importStar(require("typescript"));
7
9
  const utils_1 = require("../utils");
10
+ const typescript_compiler_options_1 = require("../utils/typescript-compiler-options");
8
11
  const assert_supported_versions_1 = require("../utils/assert-supported-versions");
9
12
  const private_1 = require("@angular/build/private");
10
13
  const targets_from_browsers_1 = require("../utils/targets-from-browsers");
11
- const private_2 = require("@angular/build/private");
12
14
  const node_module_1 = require("node:module");
13
15
  exports.DEFAULT_NG_COMPILER_OPTIONS = {
14
16
  suppressOutputPathCheck: true,
15
17
  outDir: undefined,
16
- sourceMap: true,
17
18
  declaration: false,
18
19
  declarationMap: false,
19
20
  allowEmptyCodegenFiles: false,
@@ -26,20 +27,75 @@ exports.DEFAULT_NG_COMPILER_OPTIONS = {
26
27
  supportJitMode: false,
27
28
  };
28
29
  let COMPONENT_STYLESHEET_BUNDLER = undefined;
30
+ /**
31
+ * Reads the project's TypeScript configuration with the Angular compiler
32
+ * defaults applied and creates (or reuses) the shared component stylesheet
33
+ * bundler. TypeScript sourcemaps are emitted inline and only when
34
+ * `options.sourceMap` is enabled. Targets below ES2022 are raised (see
35
+ * `applyEs2022TargetDefaults`), unsupported `module` values are set to
36
+ * ES2022, and partial compilation mode is forced to full, each with a
37
+ * warning in the returned `setupWarnings`. Combining `isolatedModules` with
38
+ * `emitDecoratorMetadata` is also warned about, without forcing either
39
+ * option.
40
+ */
29
41
  async function setupCompilation(config, options) {
30
42
  (0, assert_supported_versions_1.assertSupportedAngularRspackCompilerVersions)();
31
43
  const { readConfiguration } = await (0, utils_1.loadCompilerCli)();
32
44
  const { options: tsCompilerOptions, rootNames } = readConfiguration(config.source?.tsconfigPath ?? options.tsConfig, {
33
45
  ...exports.DEFAULT_NG_COMPILER_OPTIONS,
46
+ // Sourcemaps must be inline to survive the loader chain, and emitting
47
+ // them forgoes Angular's fast raw-TS emit path, so only emit them when
48
+ // script sourcemaps are requested.
49
+ inlineSources: !!options.sourceMap,
50
+ inlineSourceMap: !!options.sourceMap,
51
+ sourceMap: undefined,
52
+ // Composite emit is unsupported and conflicts with the incremental
53
+ // state handling; force it off.
54
+ composite: false,
55
+ // The bundler resolves symlinks based on this option alone; the
56
+ // program must resolve the same way, so the tsconfig value is ignored.
57
+ preserveSymlinks: options.preserveSymlinks,
34
58
  ...(options.useTsProjectReferences
35
59
  ? {
36
60
  sourceMap: false,
61
+ inlineSourceMap: false,
37
62
  inlineSources: false,
38
63
  isolatedModules: true,
39
64
  }
40
65
  : {}),
41
66
  });
42
67
  const compilerOptions = tsCompilerOptions;
68
+ const setupWarnings = [];
69
+ const hasExplicitUseDefineForClassFields = compilerOptions.useDefineForClassFields !== undefined;
70
+ if ((0, typescript_compiler_options_1.applyEs2022TargetDefaults)(compilerOptions)) {
71
+ setupWarnings.push(hasExplicitUseDefineForClassFields
72
+ ? "TypeScript compiler option 'target' is set to 'ES2022'."
73
+ : "TypeScript compiler options 'target' and 'useDefineForClassFields' are set to 'ES2022' and 'false' respectively.");
74
+ }
75
+ // Partial compilation output requires the Angular linker, which the JS
76
+ // transformer skips for application code; it would ship unlinked and fail
77
+ // at runtime.
78
+ if (compilerOptions.compilationMode === 'partial') {
79
+ setupWarnings.push('Angular partial compilation mode is not supported when building applications. Full compilation mode will be used instead.');
80
+ compilerOptions.compilationMode = 'full';
81
+ }
82
+ if (compilerOptions.module === undefined ||
83
+ compilerOptions.module < ts.ModuleKind.ES2015) {
84
+ compilerOptions.module = ts.ModuleKind.ES2022;
85
+ setupWarnings.push("TypeScript compiler options 'module' values 'CommonJS', 'UMD', 'System' and 'AMD' are not supported. The 'module' option will be set to 'ES2022' instead.");
86
+ }
87
+ if (compilerOptions.isolatedModules &&
88
+ compilerOptions.emitDecoratorMetadata) {
89
+ setupWarnings.push("TypeScript compiler option 'isolatedModules' may prevent the 'emitDecoratorMetadata' option from emitting all metadata. " +
90
+ "The 'emitDecoratorMetadata' option is not required by Angular and can be removed if not explicitly required by the project.");
91
+ }
92
+ // With bundler-style resolution the program resolves package exports with
93
+ // these conditions; keep them in step with the bundler's custom
94
+ // conditions so both resolve the same files.
95
+ if (compilerOptions.moduleResolution === ts.ModuleResolutionKind.Bundler ||
96
+ compilerOptions.module === ts.ModuleKind.Preserve) {
97
+ compilerOptions.customConditions = options.customConditions;
98
+ }
43
99
  const searchDirectories = await (0, private_1.generateSearchDirectories)([options.root]);
44
100
  const postcssConfiguration = await (0, private_1.loadPostcssConfiguration)(searchDirectories);
45
101
  // Skip tailwind configuration if postcss is customized
@@ -69,18 +125,19 @@ async function setupCompilation(config, options) {
69
125
  media: `media/${config.mode === 'production' ? '[name]-[hash]' : '[name]'}`,
70
126
  },
71
127
  sourcemap: false,
72
- target: (0, targets_from_browsers_1.transformSupportedBrowsersToTargets)((0, private_2.getSupportedBrowsers)(options.root, {
128
+ target: (0, targets_from_browsers_1.transformSupportedBrowsersToTargets)((0, private_1.getSupportedBrowsers)(options.root, {
73
129
  warn: (message) => console.warn(message),
74
130
  })),
75
131
  includePaths: options.includePaths,
76
132
  sass: options.sass,
77
133
  postcssConfiguration,
78
134
  tailwindConfiguration,
79
- }, options.inlineStyleLanguage, false));
135
+ }, options.inlineStyleLanguage, !!options.watch));
80
136
  return {
81
137
  rootNames,
82
138
  compilerOptions,
83
139
  componentStylesheetBundler: COMPONENT_STYLESHEET_BUNDLER,
140
+ setupWarnings,
84
141
  };
85
142
  }
86
143
  /**
@@ -117,10 +174,10 @@ function styleTransform(componentStylesheetBundler) {
117
174
  console.error('Failed to compile styles. Continuing execution ignoring failing stylesheet...', error.text);
118
175
  }
119
176
  }
120
- // Return both contents and outputFiles
121
177
  return {
122
178
  contents: stylesheetResult.contents,
123
179
  outputFiles: stylesheetResult.outputFiles,
180
+ metafile: stylesheetResult.metafile,
124
181
  };
125
182
  }
126
183
  catch (e) {
@@ -1,11 +1,25 @@
1
1
  import type { RsbuildConfig } from '@rsbuild/core';
2
2
  import { AngularCompilation, SourceFileCache } from '../models';
3
3
  import { SetupCompilationOptions } from './setup-compilation';
4
+ /**
5
+ * The files bundled into a component stylesheet, keyed by the stylesheet
6
+ * they were bundled from. Used to attribute package licenses.
7
+ */
8
+ export interface StylesheetMetafileInputs {
9
+ source: string;
10
+ inputs: Record<string, {
11
+ bytesInOutput: number;
12
+ }>;
13
+ }
4
14
  export declare function setupCompilationWithAngularCompilation(config: Pick<RsbuildConfig, 'source'>, options: SetupCompilationOptions, sourceFileCache?: SourceFileCache, angularCompilation?: AngularCompilation, modifiedFiles?: Set<string>): Promise<{
5
15
  angularCompilation: AngularCompilation;
6
16
  collectedStylesheetAssets: {
7
17
  path: string;
8
18
  text: string;
9
19
  }[];
20
+ collectedStylesheetMetafileInputs: StylesheetMetafileInputs[];
21
+ useTypeScriptTranspilation: boolean;
22
+ resourceDependencies: Map<string, readonly string[]>;
23
+ setupWarnings: string[];
10
24
  }>;
11
25
  //# sourceMappingURL=setup-with-angular-compilation.d.ts.map
@@ -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;AACnD,OAAO,EAEL,kBAAkB,EAClB,eAAe,EAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAGL,uBAAuB,EAExB,MAAM,qBAAqB,CAAC;AAE7B,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;;;cAkBoB,MAAM;cAAQ,MAAM;;GA2CpE"}
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"}
@@ -1,11 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setupCompilationWithAngularCompilation = setupCompilationWithAngularCompilation;
4
+ const node_path_1 = require("node:path");
4
5
  const models_1 = require("../models");
5
6
  const setup_compilation_1 = require("./setup-compilation");
6
7
  async function setupCompilationWithAngularCompilation(config, options, sourceFileCache, angularCompilation, modifiedFiles) {
7
- const { rootNames, compilerOptions, componentStylesheetBundler } = await (0, setup_compilation_1.setupCompilation)(config, options);
8
- angularCompilation ?? (angularCompilation = await (0, models_1.createAngularCompilation)(!options.aot, !options.hasServer, false));
8
+ const { rootNames, compilerOptions, componentStylesheetBundler, setupWarnings, } = await (0, setup_compilation_1.setupCompilation)(config, options);
9
+ // Persist the TypeScript incremental state to the cache directory when one
10
+ // is available so later cold builds resume from it.
11
+ if (sourceFileCache?.persistentCachePath &&
12
+ compilerOptions.incremental !== false) {
13
+ compilerOptions.incremental = true;
14
+ compilerOptions.tsBuildInfoFile = (0, node_path_1.join)(sourceFileCache.persistentCachePath, '.tsbuildinfo');
15
+ }
16
+ else {
17
+ compilerOptions.incremental = false;
18
+ }
19
+ // Mirrors @angular/build's NG_BUILD_PARALLEL_TS switch: anything but
20
+ // 0/false runs the Angular compilation in a worker thread, so type
21
+ // checking overlaps with the bundling work.
22
+ const parallelTs = process.env['NG_BUILD_PARALLEL_TS'];
23
+ let createdAngularCompilation = false;
24
+ if (!angularCompilation) {
25
+ try {
26
+ angularCompilation = await (0, models_1.createAngularCompilation)(!options.aot, !options.hasServer, parallelTs !== '0' && parallelTs?.toLowerCase() !== 'false');
27
+ }
28
+ catch (error) {
29
+ attachSetupWarnings(error, setupWarnings);
30
+ throw error;
31
+ }
32
+ createdAngularCompilation = true;
33
+ }
34
+ // Drop the bundler's cached results for changed files so dependent
35
+ // stylesheets get rebuilt; there's nothing to invalidate on the first build.
36
+ if (modifiedFiles) {
37
+ componentStylesheetBundler.invalidate(modifiedFiles);
38
+ }
9
39
  modifiedFiles ?? (modifiedFiles = new Set(rootNames));
10
40
  const fileReplacements = options.fileReplacements.reduce((r, f) => {
11
41
  r[f.replace] = f.with;
@@ -13,34 +43,100 @@ async function setupCompilationWithAngularCompilation(config, options, sourceFil
13
43
  }, {});
14
44
  // Store collected stylesheet output files
15
45
  const collectedStylesheetAssets = [];
46
+ const collectedStylesheetMetafileInputs = [];
16
47
  // Create a wrapper around styleTransform to collect outputFiles
17
48
  const transformFn = (0, setup_compilation_1.styleTransform)(componentStylesheetBundler);
18
- const wrappedTransformStylesheet = async (styles, containingFile, stylesheetFile) => {
49
+ const wrappedTransformStylesheet = async (styles, containingFile, stylesheetFile, order, className) => {
19
50
  const result = await transformFn(styles, containingFile, stylesheetFile);
20
51
  // Collect outputFiles if present
21
52
  if (result.outputFiles && result.outputFiles.length > 0) {
22
53
  collectedStylesheetAssets.push(...result.outputFiles);
23
54
  }
55
+ if (result.metafile) {
56
+ // Inline styles share the containing file; disambiguate with the
57
+ // class name and order so entries stay unique per stylesheet.
58
+ let source = stylesheetFile ?? containingFile;
59
+ if (!stylesheetFile) {
60
+ source += `?class=${className}&order=${order}`;
61
+ }
62
+ const inputs = {};
63
+ for (const output of Object.values(result.metafile.outputs)) {
64
+ Object.assign(inputs, output.inputs);
65
+ }
66
+ collectedStylesheetMetafileInputs.push({ source, inputs });
67
+ }
24
68
  // Return just the contents string as expected by Angular compilation
25
69
  return result.contents;
26
70
  };
27
- // Initialization errors are intentionally not caught here: callers must
28
- // surface them as build errors instead of continuing with a compilation
29
- // that was never initialized.
30
- const { referencedFiles } = await angularCompilation.initialize(config.source?.tsconfigPath ?? options.tsConfig, {
31
- sourceFileCache,
32
- fileReplacements,
33
- modifiedFiles,
34
- transformStylesheet: wrappedTransformStylesheet,
35
- processWebWorker(workerFile) {
36
- return workerFile;
37
- },
38
- }, () => compilerOptions);
71
+ // Initialization errors are rethrown for callers to surface as build
72
+ // errors instead of continuing with a compilation that was never
73
+ // initialized.
74
+ let initializationResult;
75
+ try {
76
+ initializationResult = await angularCompilation.initialize(config.source?.tsconfigPath ?? options.tsConfig, {
77
+ sourceFileCache,
78
+ fileReplacements,
79
+ modifiedFiles,
80
+ transformStylesheet: wrappedTransformStylesheet,
81
+ processWebWorker(workerFile) {
82
+ return workerFile;
83
+ },
84
+ }, () => compilerOptions);
85
+ }
86
+ catch (error) {
87
+ // A worker-based compilation spawns its worker thread on construction;
88
+ // close one created here or every failing setup would leak a worker.
89
+ // A caller-provided compilation stays alive for the caller to reuse.
90
+ if (createdAngularCompilation) {
91
+ try {
92
+ await angularCompilation.close?.();
93
+ }
94
+ catch {
95
+ // The initialization error is the one worth surfacing.
96
+ }
97
+ }
98
+ attachSetupWarnings(error, setupWarnings);
99
+ throw error;
100
+ }
101
+ const { compilerOptions: initializedCompilerOptions, referencedFiles, componentResourcesDependencies, } = initializationResult;
39
102
  if (sourceFileCache) {
40
103
  sourceFileCache.referencedFiles = referencedFiles;
41
104
  }
105
+ // The compiler already tracks each source file's template and stylesheet
106
+ // dependencies; re-key them like the emit cache so loaders can register
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.
110
+ let resourceDependencies;
111
+ if (componentResourcesDependencies) {
112
+ resourceDependencies = new Map();
113
+ for (const [file, dependencies] of componentResourcesDependencies) {
114
+ resourceDependencies.set((0, models_1.toTypeScriptFileCacheKey)(file), dependencies);
115
+ }
116
+ }
117
+ // Only the AOT emit branches between TypeScript transpilation and raw
118
+ // Angular-transformed TypeScript, on this exact expression over the
119
+ // program's options (JIT always transpiles). The loaders classify the
120
+ // emitted cache entries with this flag, so it must never diverge from the
121
+ // emit's gate. The worker-based initialize reports only four options; the
122
+ // three the gate reads are among them, and any other option would be
123
+ // undefined here.
124
+ const useTypeScriptTranspilation = !initializedCompilerOptions?.isolatedModules ||
125
+ !!initializedCompilerOptions?.sourceMap ||
126
+ !!initializedCompilerOptions?.inlineSourceMap;
42
127
  return {
43
128
  angularCompilation,
44
129
  collectedStylesheetAssets,
130
+ collectedStylesheetMetafileInputs,
131
+ useTypeScriptTranspilation,
132
+ resourceDependencies,
133
+ setupWarnings,
45
134
  };
46
135
  }
136
+ // Callers report initialization failures as build errors; hand them the
137
+ // setup warnings so they are not lost with the failed build.
138
+ function attachSetupWarnings(error, setupWarnings) {
139
+ if (error && typeof error === 'object') {
140
+ error.setupWarnings = setupWarnings;
141
+ }
142
+ }
@@ -1,5 +1,6 @@
1
- import { JavaScriptTransformer, SourceFileCache, AngularCompilation, createAngularCompilation } from '@angular/build/private';
2
- export { JavaScriptTransformer, SourceFileCache, AngularCompilation, createAngularCompilation, };
1
+ import { JavaScriptTransformer, AngularCompilation, createAngularCompilation } from '@angular/build/private';
2
+ export { JavaScriptTransformer, AngularCompilation, createAngularCompilation };
3
+ export { SourceFileCache, toTypeScriptFileCacheKey, type BabelFileCacheEntry, type TransformedSource, } from '../utils/source-file-cache';
3
4
  export * from './inline-style-language';
4
5
  export * from './file-replacement';
5
6
  export * from './style-preprocessor-options';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,wBAAwB,GACzB,CAAC;AAEF,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAE7C,oBAAY,eAAe;IACzB,IAAI,IAAI;IACR,MAAM,IAAS;IACf,SAAS,IAAS;IAClB,QAAQ,IAAS;IACjB,GAAG,IAAgC;CACpC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACpC,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,CAAC;AAC/E,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACvB,MAAM,4BAA4B,CAAC;AAEpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAE7C,oBAAY,eAAe;IACzB,IAAI,IAAI;IACR,MAAM,IAAS;IACf,SAAS,IAAS;IAClB,QAAQ,IAAS;IACjB,GAAG,IAAgC;CACpC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACpC,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB"}
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DiagnosticModes = exports.createAngularCompilation = exports.SourceFileCache = exports.JavaScriptTransformer = void 0;
3
+ exports.DiagnosticModes = exports.toTypeScriptFileCacheKey = exports.SourceFileCache = exports.createAngularCompilation = exports.JavaScriptTransformer = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const private_1 = require("@angular/build/private");
6
6
  Object.defineProperty(exports, "JavaScriptTransformer", { enumerable: true, get: function () { return private_1.JavaScriptTransformer; } });
7
- Object.defineProperty(exports, "SourceFileCache", { enumerable: true, get: function () { return private_1.SourceFileCache; } });
8
7
  Object.defineProperty(exports, "createAngularCompilation", { enumerable: true, get: function () { return private_1.createAngularCompilation; } });
8
+ var source_file_cache_1 = require("../utils/source-file-cache");
9
+ Object.defineProperty(exports, "SourceFileCache", { enumerable: true, get: function () { return source_file_cache_1.SourceFileCache; } });
10
+ Object.defineProperty(exports, "toTypeScriptFileCacheKey", { enumerable: true, get: function () { return source_file_cache_1.toTypeScriptFileCacheKey; } });
9
11
  tslib_1.__exportStar(require("./inline-style-language"), exports);
10
12
  tslib_1.__exportStar(require("./file-replacement"), exports);
11
13
  tslib_1.__exportStar(require("./style-preprocessor-options"), exports);
@@ -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,5 +1,7 @@
1
1
  export * from './regex-filters';
2
2
  export * from './component-resolvers';
3
+ export * from './javascript-transformer-cache';
3
4
  export * from './load-compiler-cli';
5
+ export * from './typescript-compiler-options';
4
6
  export { maxWorkers } from './utils';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
@@ -4,6 +4,8 @@ exports.maxWorkers = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  tslib_1.__exportStar(require("./regex-filters"), exports);
6
6
  tslib_1.__exportStar(require("./component-resolvers"), exports);
7
+ tslib_1.__exportStar(require("./javascript-transformer-cache"), exports);
7
8
  tslib_1.__exportStar(require("./load-compiler-cli"), exports);
9
+ tslib_1.__exportStar(require("./typescript-compiler-options"), exports);
8
10
  var utils_1 = require("./utils");
9
11
  Object.defineProperty(exports, "maxWorkers", { enumerable: true, get: function () { return utils_1.maxWorkers; } });
@@ -0,0 +1,18 @@
1
+ import type { Cache } from '@angular/build/private';
2
+ export interface JavascriptTransformerCache {
3
+ cache: Cache<Uint8Array>;
4
+ close(): Promise<void>;
5
+ }
6
+ /**
7
+ * Creates the persistent store the esbuild application builder uses for
8
+ * `JavaScriptTransformer` results, so Angular package linking is only paid
9
+ * on the first build with a given cache directory.
10
+ *
11
+ * The LMDB-backed store is not part of `@angular/build`'s exported API and
12
+ * its exports map blocks subpath imports, so it is loaded from the resolved
13
+ * package location. Returns `undefined` when it cannot be loaded (older
14
+ * `@angular/build` versions, platforms without lmdb prebuilds), in which
15
+ * case the transformer runs uncached.
16
+ */
17
+ export declare function createJavascriptTransformerCache(persistentCachePath: string): JavascriptTransformerCache | undefined;
18
+ //# sourceMappingURL=javascript-transformer-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"javascript-transformer-cache.d.ts","sourceRoot":"","sources":["../../src/utils/javascript-transformer-cache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,mBAAmB,EAAE,MAAM,GAC1B,0BAA0B,GAAG,SAAS,CAmBxC"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createJavascriptTransformerCache = createJavascriptTransformerCache;
4
+ const node_module_1 = require("node:module");
5
+ const node_path_1 = require("node:path");
6
+ /**
7
+ * Creates the persistent store the esbuild application builder uses for
8
+ * `JavaScriptTransformer` results, so Angular package linking is only paid
9
+ * on the first build with a given cache directory.
10
+ *
11
+ * The LMDB-backed store is not part of `@angular/build`'s exported API and
12
+ * its exports map blocks subpath imports, so it is loaded from the resolved
13
+ * package location. Returns `undefined` when it cannot be loaded (older
14
+ * `@angular/build` versions, platforms without lmdb prebuilds), in which
15
+ * case the transformer runs uncached.
16
+ */
17
+ function createJavascriptTransformerCache(persistentCachePath) {
18
+ try {
19
+ const requireFn = (0, node_module_1.createRequire)(__filename);
20
+ const angularBuildDir = (0, node_path_1.dirname)(requireFn.resolve('@angular/build/package.json'));
21
+ const { LmdbCacheStore } = requireFn((0, node_path_1.join)(angularBuildDir, 'src/tools/esbuild/lmdb-cache-store.js'));
22
+ const store = new LmdbCacheStore((0, node_path_1.join)(persistentCachePath, 'angular-compiler.db'));
23
+ return {
24
+ cache: store.createCache('jstransformer'),
25
+ close: () => store.close(),
26
+ };
27
+ }
28
+ catch {
29
+ return undefined;
30
+ }
31
+ }
@@ -1,4 +1,6 @@
1
1
  export declare const TS_ALL_EXT_REGEX: RegExp;
2
+ export declare const TS_EXT_REGEX: RegExp;
3
+ export declare const TSX_EXT_REGEX: RegExp;
2
4
  export declare const JS_ALL_EXT_REGEX: RegExp;
3
5
  export declare const JS_EXT_REGEX: RegExp;
4
6
  export declare function isStandardJsFile(filename: string): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"regex-filters.d.ts","sourceRoot":"","sources":["../../src/utils/regex-filters.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,QAAsB,CAAC;AACpD,eAAO,MAAM,gBAAgB,QAAsB,CAAC;AACpD,eAAO,MAAM,YAAY,QAAe,CAAC;AAEzC,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,WAEhD"}
1
+ {"version":3,"file":"regex-filters.d.ts","sourceRoot":"","sources":["../../src/utils/regex-filters.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,QAAsB,CAAC;AACpD,eAAO,MAAM,YAAY,QAAoB,CAAC;AAC9C,eAAO,MAAM,aAAa,QAAgB,CAAC;AAC3C,eAAO,MAAM,gBAAgB,QAAsB,CAAC;AACpD,eAAO,MAAM,YAAY,QAAe,CAAC;AAEzC,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,WAEhD"}
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JS_EXT_REGEX = exports.JS_ALL_EXT_REGEX = exports.TS_ALL_EXT_REGEX = void 0;
3
+ exports.JS_EXT_REGEX = exports.JS_ALL_EXT_REGEX = exports.TSX_EXT_REGEX = exports.TS_EXT_REGEX = exports.TS_ALL_EXT_REGEX = void 0;
4
4
  exports.isStandardJsFile = isStandardJsFile;
5
5
  exports.TS_ALL_EXT_REGEX = /\.[cm]?tsx?(\?|$)/;
6
+ exports.TS_EXT_REGEX = /\.[cm]?ts(\?|$)/;
7
+ exports.TSX_EXT_REGEX = /\.tsx(\?|$)/;
6
8
  exports.JS_ALL_EXT_REGEX = /\.[cm]?jsx?(\?|$)/;
7
9
  exports.JS_EXT_REGEX = /\.[cm]?js$/;
8
10
  function isStandardJsFile(filename) {
@@ -6,13 +6,54 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import type ts from 'typescript';
9
+ /**
10
+ * Angular compilation output after the JavaScript transformer has run, with
11
+ * any inline sourcemap already split off the code.
12
+ */
13
+ export interface TransformedSource {
14
+ code: string;
15
+ map: string | undefined;
16
+ }
17
+ /**
18
+ * A {@link TransformedSource} produced under a specific loader-chained input
19
+ * sourcemap. The JavaScript transformer reads and merges a file's external
20
+ * sourcemap itself, so the entry is only valid while that map is unchanged;
21
+ * `chainedMap` holds the serialized map the entry was produced with.
22
+ */
23
+ export interface BabelFileCacheEntry extends TransformedSource {
24
+ chainedMap: string | undefined;
25
+ }
26
+ /**
27
+ * Key used by `typeScriptFileCache`: the normalized path with any Windows
28
+ * drive letter stripped, so emitted filenames and loader resource paths match.
29
+ */
30
+ export declare function toTypeScriptFileCacheKey(file: string): string;
9
31
  export declare class SourceFileCache extends Map<string, ts.SourceFile> {
10
32
  readonly persistentCachePath?: string;
11
33
  readonly modifiedFiles: Set<string>;
12
- readonly babelFileCache: Map<string, Uint8Array<ArrayBufferLike>>;
13
- readonly typeScriptFileCache: Map<string, string | Uint8Array<ArrayBufferLike>>;
34
+ /**
35
+ * Emitted build output keyed by {@link toTypeScriptFileCacheKey}. A `string`
36
+ * entry is the raw, untransformed emit; the loaders replace it in place with
37
+ * a {@link TransformedSource} once the JavaScript transformer has run.
38
+ * Overwriting an entry with a fresh raw emit evicts the stale transform.
39
+ */
40
+ readonly typeScriptFileCache: Map<string, string | TransformedSource>;
41
+ /**
42
+ * JavaScript transformer output for files outside the Angular compilation
43
+ * (e.g. package code), split into code and forwarded sourcemap, keyed by
44
+ * {@link toTypeScriptFileCacheKey}. These are never re-emitted, so
45
+ * modifying a file must evict its entry; a changed chained input map
46
+ * invalidates an entry at the consumer instead (see
47
+ * {@link BabelFileCacheEntry}).
48
+ */
49
+ readonly babelFileCache: Map<string, BabelFileCacheEntry>;
14
50
  referencedFiles?: readonly string[];
15
51
  constructor(persistentCachePath?: string);
16
52
  invalidate(files: Iterable<string>): void;
53
+ /**
54
+ * Drops output cached for files deleted from disk. Modified files don't
55
+ * need this for emitted output: their next emit overwrites the entry.
56
+ */
57
+ prune(removedFiles: Iterable<string>): void;
17
58
  }
18
59
  //# sourceMappingURL=source-file-cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-file-cache.d.ts","sourceRoot":"","sources":["../../src/utils/source-file-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAKjC,qBAAa,eAAgB,SAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC;IAOjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM;IANjD,QAAQ,CAAC,aAAa,cAAqB;IAC3C,QAAQ,CAAC,cAAc,2CAAiC;IACxD,QAAQ,CAAC,mBAAmB,oDAA0C;IAEtE,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEpC,YAAqB,mBAAmB,CAAC,EAAE,MAAM,EAEhD;IAED,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAgBxC;CACF"}
1
+ {"version":3,"file":"source-file-cache.d.ts","sourceRoot":"","sources":["../../src/utils/source-file-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAKjC;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,qBAAa,eAAgB,SAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC;IAuBjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM;IAtBjD,QAAQ,CAAC,aAAa,cAAqB;IAE3C;;;;;OAKG;IACH,QAAQ,CAAC,mBAAmB,0CAAiD;IAE7E;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,mCAA0C;IAEjE,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEpC,YAAqB,mBAAmB,CAAC,EAAE,MAAM,EAEhD;IAED,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAiBxC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAM1C;CACF"}
@@ -8,26 +8,47 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.SourceFileCache = void 0;
11
+ exports.toTypeScriptFileCacheKey = toTypeScriptFileCacheKey;
11
12
  const tslib_1 = require("tslib");
12
13
  const path = tslib_1.__importStar(require("node:path"));
13
- const node_url_1 = require("node:url");
14
14
  const utils_1 = require("./utils");
15
15
  const WINDOWS_SEP_REGEXP = new RegExp(`\\${path.win32.sep}`, 'g');
16
+ /**
17
+ * Key used by `typeScriptFileCache`: the normalized path with any Windows
18
+ * drive letter stripped, so emitted filenames and loader resource paths match.
19
+ */
20
+ function toTypeScriptFileCacheKey(file) {
21
+ return path.normalize(file.replace(/^[A-Z]:/, ''));
22
+ }
16
23
  class SourceFileCache extends Map {
17
24
  constructor(persistentCachePath) {
18
25
  super();
19
26
  this.persistentCachePath = persistentCachePath;
20
27
  this.modifiedFiles = new Set();
21
- this.babelFileCache = new Map();
28
+ /**
29
+ * Emitted build output keyed by {@link toTypeScriptFileCacheKey}. A `string`
30
+ * entry is the raw, untransformed emit; the loaders replace it in place with
31
+ * a {@link TransformedSource} once the JavaScript transformer has run.
32
+ * Overwriting an entry with a fresh raw emit evicts the stale transform.
33
+ */
22
34
  this.typeScriptFileCache = new Map();
35
+ /**
36
+ * JavaScript transformer output for files outside the Angular compilation
37
+ * (e.g. package code), split into code and forwarded sourcemap, keyed by
38
+ * {@link toTypeScriptFileCacheKey}. These are never re-emitted, so
39
+ * modifying a file must evict its entry; a changed chained input map
40
+ * invalidates an entry at the consumer instead (see
41
+ * {@link BabelFileCacheEntry}).
42
+ */
43
+ this.babelFileCache = new Map();
23
44
  }
24
45
  invalidate(files) {
25
46
  if (files !== this.modifiedFiles) {
26
47
  this.modifiedFiles.clear();
27
48
  }
28
49
  for (let file of files) {
29
- this.babelFileCache.delete(file);
30
- this.typeScriptFileCache.delete((0, node_url_1.pathToFileURL)(file).href);
50
+ this.babelFileCache.delete(toTypeScriptFileCacheKey(file));
51
+ file = path.normalize(file);
31
52
  // Normalize separators to allow matching TypeScript Host paths
32
53
  if ((0, utils_1.isUsingWindows)()) {
33
54
  file = file.replace(WINDOWS_SEP_REGEXP, path.posix.sep);
@@ -36,5 +57,16 @@ class SourceFileCache extends Map {
36
57
  this.modifiedFiles.add(file);
37
58
  }
38
59
  }
60
+ /**
61
+ * Drops output cached for files deleted from disk. Modified files don't
62
+ * need this for emitted output: their next emit overwrites the entry.
63
+ */
64
+ prune(removedFiles) {
65
+ for (const file of removedFiles) {
66
+ const key = toTypeScriptFileCacheKey(file);
67
+ this.typeScriptFileCache.delete(key);
68
+ this.babelFileCache.delete(key);
69
+ }
70
+ }
39
71
  }
40
72
  exports.SourceFileCache = SourceFileCache;
@@ -0,0 +1,41 @@
1
+ import * as ts from 'typescript';
2
+ /**
3
+ * Raises `target` to ES2022, the syntax the bundling pipeline emits
4
+ * regardless of the configured target, defaulting `useDefineForClassFields`
5
+ * to `false` in that case to keep the assignment semantics a lower target
6
+ * implied. Returns whether the options were adjusted so callers can surface
7
+ * a setup warning.
8
+ */
9
+ export declare function applyEs2022TargetDefaults(compilerOptions: ts.CompilerOptions): boolean;
10
+ /**
11
+ * The `jsc.transform` options for the swc rule that transpiles TypeScript
12
+ * emitted by the Angular compilation (and raw sources), derived from the
13
+ * project's tsconfig so the output keeps the semantics the type program
14
+ * assumed.
15
+ */
16
+ export interface SwcTranspilationTransform {
17
+ legacyDecorator: boolean;
18
+ /**
19
+ * The revision applied for standard (TC39) decorators
20
+ * (`legacyDecorator: false`); swc's default revision predates the
21
+ * semantics TypeScript implements.
22
+ */
23
+ decoratorVersion?: '2022-03' | '2023-11';
24
+ decoratorMetadata: boolean;
25
+ useDefineForClassFields: boolean;
26
+ verbatimModuleSyntax: boolean;
27
+ /**
28
+ * JSX lowering for `.tsx` sources, read from the tsconfig the way esbuild
29
+ * does: the automatic runtime for 'react-jsx'/'react-jsxdev', the classic
30
+ * transform otherwise ('preserve' included; esbuild lowers it too).
31
+ */
32
+ react: {
33
+ runtime: 'automatic' | 'classic';
34
+ development: boolean;
35
+ pragma?: string;
36
+ pragmaFrag?: string;
37
+ importSource?: string;
38
+ };
39
+ }
40
+ export declare function resolveSwcTranspilationTransform(tsconfigPath: string, standardDecoratorVersion: '2022-03' | '2023-11'): SwcTranspilationTransform;
41
+ //# sourceMappingURL=typescript-compiler-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript-compiler-options.d.ts","sourceRoot":"","sources":["../../src/utils/typescript-compiler-options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,EAAE,CAAC,eAAe,GAClC,OAAO,CAUT;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IACzC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uBAAuB,EAAE,OAAO,CAAC;IACjC,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,KAAK,EAAE;QACL,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC;QACjC,WAAW,EAAE,OAAO,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,wBAAgB,gCAAgC,CAC9C,YAAY,EAAE,MAAM,EACpB,wBAAwB,EAAE,SAAS,GAAG,SAAS,GAC9C,yBAAyB,CAiC3B"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyEs2022TargetDefaults = applyEs2022TargetDefaults;
4
+ exports.resolveSwcTranspilationTransform = resolveSwcTranspilationTransform;
5
+ const tslib_1 = require("tslib");
6
+ const node_path_1 = require("node:path");
7
+ const ts = tslib_1.__importStar(require("typescript"));
8
+ /**
9
+ * Raises `target` to ES2022, the syntax the bundling pipeline emits
10
+ * regardless of the configured target, defaulting `useDefineForClassFields`
11
+ * to `false` in that case to keep the assignment semantics a lower target
12
+ * implied. Returns whether the options were adjusted so callers can surface
13
+ * a setup warning.
14
+ */
15
+ function applyEs2022TargetDefaults(compilerOptions) {
16
+ if (compilerOptions.target === undefined ||
17
+ compilerOptions.target < ts.ScriptTarget.ES2022) {
18
+ compilerOptions.target = ts.ScriptTarget.ES2022;
19
+ compilerOptions.useDefineForClassFields ?? (compilerOptions.useDefineForClassFields = false);
20
+ return true;
21
+ }
22
+ return false;
23
+ }
24
+ function resolveSwcTranspilationTransform(tsconfigPath, standardDecoratorVersion) {
25
+ // Read errors are reported in-band and deliberately ignored: a missing or
26
+ // malformed tsconfig recovers to the forced defaults here, and the build
27
+ // still fails through rspack's own resolution of the same tsconfig path.
28
+ const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
29
+ const compilerOptions = {
30
+ ...ts.parseJsonConfigFileContent(configFile.config, ts.sys, (0, node_path_1.dirname)(tsconfigPath)).options,
31
+ };
32
+ applyEs2022TargetDefaults(compilerOptions);
33
+ const legacyDecorator = !!compilerOptions.experimentalDecorators;
34
+ return {
35
+ legacyDecorator,
36
+ ...(legacyDecorator ? {} : { decoratorVersion: standardDecoratorVersion }),
37
+ // Design-type metadata comes from the type checker; swc emits what the
38
+ // annotations alone provide, which is as much as a per-file transpiler
39
+ // can honor.
40
+ decoratorMetadata: legacyDecorator && !!compilerOptions.emitDecoratorMetadata,
41
+ // With the target raised to ES2022 the forced default is false; an
42
+ // ES2022+ tsconfig without the option gets TypeScript's default. For a
43
+ // target-less tsconfig esbuild instead uses its own default of true,
44
+ // contradicting the program options it forces; we follow the program.
45
+ useDefineForClassFields: compilerOptions.useDefineForClassFields ?? true,
46
+ verbatimModuleSyntax: !!compilerOptions.verbatimModuleSyntax,
47
+ react: resolveJsxTransform(compilerOptions),
48
+ };
49
+ }
50
+ // swc's factory defaults (React.createElement, React.Fragment, 'react')
51
+ // match esbuild's, so the options are only set when the tsconfig sets them.
52
+ function resolveJsxTransform(compilerOptions) {
53
+ const { jsx, jsxFactory, jsxFragmentFactory, jsxImportSource } = compilerOptions;
54
+ return {
55
+ runtime: jsx === ts.JsxEmit.ReactJSX || jsx === ts.JsxEmit.ReactJSXDev
56
+ ? 'automatic'
57
+ : 'classic',
58
+ development: jsx === ts.JsxEmit.ReactJSXDev,
59
+ ...(jsxFactory ? { pragma: jsxFactory } : {}),
60
+ ...(jsxFragmentFactory ? { pragmaFrag: jsxFragmentFactory } : {}),
61
+ ...(jsxImportSource ? { importSource: jsxImportSource } : {}),
62
+ };
63
+ }
@@ -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.1",
4
+ "version": "23.2.0-beta.11",
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.1"
47
+ "@nx/devkit": "23.2.0-beta.11"
49
48
  },
50
49
  "devDependencies": {
51
50
  "jsonc-eslint-parser": "^2.4.0",
@@ -3,9 +3,8 @@ const { gte, coerce } = require('semver');
3
3
  const { dirname, join } = require('path');
4
4
 
5
5
  function main() {
6
- const angularBuildPackageJson = require.resolve(
7
- '@angular/build/package.json'
8
- );
6
+ const angularBuildPackageJson =
7
+ require.resolve('@angular/build/package.json');
9
8
  const fileContentsJson = JSON.parse(
10
9
  readFileSync(angularBuildPackageJson, 'utf8')
11
10
  );