@nx/angular-rspack 20.9.0 → 21.0.0

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 (88) hide show
  1. package/dist/lib/config/config-utils/browser-config.d.ts.map +1 -1
  2. package/dist/lib/config/config-utils/browser-config.js +11 -0
  3. package/dist/lib/config/config-utils/common-config.d.ts.map +1 -1
  4. package/dist/lib/config/config-utils/common-config.js +32 -0
  5. package/dist/lib/config/config-utils/dev-server-config-utils.d.ts.map +1 -1
  6. package/dist/lib/config/config-utils/dev-server-config-utils.js +3 -1
  7. package/dist/lib/config/config-utils/get-stats-options.d.ts +3 -0
  8. package/dist/lib/config/config-utils/get-stats-options.d.ts.map +1 -0
  9. package/dist/lib/config/config-utils/get-stats-options.js +39 -0
  10. package/dist/lib/config/config-utils/optimization-config.d.ts.map +1 -1
  11. package/dist/lib/config/config-utils/optimization-config.js +3 -1
  12. package/dist/lib/config/config-utils/server-config.d.ts.map +1 -1
  13. package/dist/lib/config/config-utils/server-config.js +2 -1
  14. package/dist/lib/config/config-utils/style-config-utils.d.ts.map +1 -1
  15. package/dist/lib/config/config-utils/style-config-utils.js +8 -9
  16. package/dist/lib/config/config-utils/user-defined-config-helpers.d.ts +7 -14
  17. package/dist/lib/config/config-utils/user-defined-config-helpers.d.ts.map +1 -1
  18. package/dist/lib/models/angular-rspack-plugin-options.d.ts +100 -6
  19. package/dist/lib/models/angular-rspack-plugin-options.d.ts.map +1 -1
  20. package/dist/lib/models/augmented-compilation.d.ts +2 -2
  21. package/dist/lib/models/augmented-compilation.d.ts.map +1 -1
  22. package/dist/lib/models/normalize-options.d.ts +2 -2
  23. package/dist/lib/models/normalize-options.d.ts.map +1 -1
  24. package/dist/lib/models/normalize-options.js +63 -28
  25. package/dist/lib/plugins/angular-rspack-plugin.d.ts.map +1 -1
  26. package/dist/lib/plugins/angular-rspack-plugin.js +58 -12
  27. package/dist/lib/plugins/any-component-style-budget-checker-plugin.d.ts +19 -0
  28. package/dist/lib/plugins/any-component-style-budget-checker-plugin.d.ts.map +1 -0
  29. package/dist/lib/plugins/any-component-style-budget-checker-plugin.js +65 -0
  30. package/dist/lib/plugins/i18n-inline-plugin.d.ts.map +1 -1
  31. package/dist/lib/plugins/i18n-inline-plugin.js +5 -3
  32. package/dist/lib/plugins/loaders/angular-partial-transform.loader.d.ts.map +1 -1
  33. package/dist/lib/plugins/loaders/angular-partial-transform.loader.js +4 -1
  34. package/dist/lib/plugins/loaders/hmr-accept-loader.d.ts +11 -0
  35. package/dist/lib/plugins/loaders/hmr-accept-loader.d.ts.map +1 -0
  36. package/dist/lib/plugins/loaders/hmr-accept-loader.js +24 -0
  37. package/dist/lib/plugins/loaders/hmr-accept.d.ts +9 -0
  38. package/dist/lib/plugins/loaders/hmr-accept.d.ts.map +1 -0
  39. package/dist/lib/plugins/loaders/hmr-accept.js +183 -0
  40. package/dist/lib/plugins/ng-rspack.d.ts.map +1 -1
  41. package/dist/lib/plugins/ng-rspack.js +35 -15
  42. package/dist/lib/plugins/prerender-plugin.d.ts.map +1 -1
  43. package/dist/lib/plugins/prerender-plugin.js +75 -10
  44. package/dist/lib/plugins/progress-plugin.d.ts +12 -0
  45. package/dist/lib/plugins/progress-plugin.d.ts.map +1 -0
  46. package/dist/lib/plugins/progress-plugin.js +36 -0
  47. package/dist/lib/plugins/stats-json-plugin.d.ts +14 -0
  48. package/dist/lib/plugins/stats-json-plugin.d.ts.map +1 -0
  49. package/dist/lib/plugins/stats-json-plugin.js +70 -0
  50. package/dist/lib/plugins/suppress-js-for-css-chunks-plugin.d.ts +5 -0
  51. package/dist/lib/plugins/suppress-js-for-css-chunks-plugin.d.ts.map +1 -0
  52. package/dist/lib/plugins/suppress-js-for-css-chunks-plugin.js +34 -0
  53. package/dist/lib/plugins/tools/dev-tools-ignore-plugin.d.ts.map +1 -1
  54. package/dist/lib/plugins/tools/dev-tools-ignore-plugin.js +1 -1
  55. package/dist/lib/plugins/transfer-size-plugin.d.ts +12 -0
  56. package/dist/lib/plugins/transfer-size-plugin.d.ts.map +1 -0
  57. package/dist/lib/plugins/transfer-size-plugin.js +49 -0
  58. package/dist/lib/plugins/watch-file-logs-plugin.d.ts +12 -0
  59. package/dist/lib/plugins/watch-file-logs-plugin.d.ts.map +1 -0
  60. package/dist/lib/plugins/watch-file-logs-plugin.js +27 -0
  61. package/dist/lib/utils/async-chunks.d.ts +17 -0
  62. package/dist/lib/utils/async-chunks.d.ts.map +1 -0
  63. package/dist/lib/utils/async-chunks.js +44 -0
  64. package/dist/lib/utils/color.d.ts +11 -0
  65. package/dist/lib/utils/color.d.ts.map +1 -0
  66. package/dist/lib/utils/color.js +41 -0
  67. package/dist/lib/utils/index-file/get-index-input-file.d.ts +3 -0
  68. package/dist/lib/utils/index-file/get-index-input-file.d.ts.map +1 -0
  69. package/dist/lib/utils/index-file/get-index-input-file.js +9 -0
  70. package/dist/lib/utils/misc-helpers.d.ts +1 -0
  71. package/dist/lib/utils/misc-helpers.d.ts.map +1 -1
  72. package/dist/lib/utils/misc-helpers.js +4 -0
  73. package/dist/lib/utils/rspack-diagnostics.d.ts +3 -3
  74. package/dist/lib/utils/rspack-diagnostics.d.ts.map +1 -1
  75. package/dist/lib/utils/rspack-diagnostics.js +16 -4
  76. package/dist/lib/utils/spinner.d.ts +21 -0
  77. package/dist/lib/utils/spinner.d.ts.map +1 -0
  78. package/dist/lib/utils/spinner.js +53 -0
  79. package/dist/lib/utils/stats.d.ts +35 -0
  80. package/dist/lib/utils/stats.d.ts.map +1 -0
  81. package/dist/lib/utils/stats.js +312 -0
  82. package/dist/lib/utils/tty.d.ts +9 -0
  83. package/dist/lib/utils/tty.d.ts.map +1 -0
  84. package/dist/lib/utils/tty.js +22 -0
  85. package/package.json +6 -2
  86. package/dist/lib/models/unsupported-options.d.ts +0 -39
  87. package/dist/lib/models/unsupported-options.d.ts.map +0 -1
  88. package/dist/lib/models/unsupported-options.js +0 -22
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.dev/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.default = default_1;
11
+ const core_1 = require("@angular/core");
12
+ const rxjs_1 = require("rxjs");
13
+ function default_1(mod) {
14
+ if (!mod['hot']) {
15
+ return;
16
+ }
17
+ if (!(0, core_1.isDevMode)()) {
18
+ console.error(`[NG HMR] Cannot use HMR when Angular is running in production mode. To prevent production mode, do not call 'enableProdMode()'.`);
19
+ return;
20
+ }
21
+ mod['hot'].accept();
22
+ mod['hot'].dispose(() => {
23
+ if (typeof ng === 'undefined') {
24
+ console.warn(`[NG HMR] Cannot find global 'ng'. Likely this is caused because scripts optimization is enabled.`);
25
+ return;
26
+ }
27
+ if (!ng.getInjector) {
28
+ // View Engine
29
+ return;
30
+ }
31
+ // Reset JIT compiled components cache
32
+ (0, core_1.ɵresetCompiledComponents)();
33
+ const appRoot = getAppRoot();
34
+ if (!appRoot) {
35
+ return;
36
+ }
37
+ const appRef = getApplicationRef(appRoot);
38
+ if (!appRef) {
39
+ return;
40
+ }
41
+ // Inputs that are hidden should be ignored
42
+ const oldInputs = document.querySelectorAll('input:not([type="hidden"]), textarea');
43
+ const oldOptions = document.querySelectorAll('option');
44
+ // Create new application
45
+ appRef.components.forEach((cp) => {
46
+ const element = cp.location.nativeElement;
47
+ const parentNode = element.parentNode;
48
+ parentNode.insertBefore(document.createElement(element.tagName), element);
49
+ parentNode.removeChild(element);
50
+ });
51
+ // Destroy old application, injectors, <style..., etc..
52
+ const platformRef = getPlatformRef(appRoot);
53
+ if (platformRef) {
54
+ platformRef.destroy();
55
+ }
56
+ // Restore all inputs and options
57
+ const bodyElement = document.body;
58
+ if (oldInputs.length + oldOptions.length === 0 || !bodyElement) {
59
+ return;
60
+ }
61
+ // Use a `MutationObserver` to wait until the app-root element has been bootstrapped.
62
+ // ie: when the ng-version attribute is added.
63
+ new MutationObserver((_mutationsList, observer) => {
64
+ observer.disconnect();
65
+ const newAppRoot = getAppRoot();
66
+ if (!newAppRoot) {
67
+ return;
68
+ }
69
+ const newAppRef = getApplicationRef(newAppRoot);
70
+ if (!newAppRef) {
71
+ return;
72
+ }
73
+ // Wait until the application isStable to restore the form values
74
+ newAppRef.isStable
75
+ .pipe((0, rxjs_1.filter)((isStable) => !!isStable), (0, rxjs_1.take)(1))
76
+ .subscribe(() => restoreFormValues(oldInputs, oldOptions));
77
+ }).observe(bodyElement, {
78
+ attributes: true,
79
+ subtree: true,
80
+ attributeFilter: ['ng-version'],
81
+ });
82
+ });
83
+ }
84
+ function getAppRoot() {
85
+ const appRoot = document.querySelector('[ng-version]');
86
+ if (!appRoot) {
87
+ console.warn('[NG HMR] Cannot find the application root component.');
88
+ return undefined;
89
+ }
90
+ return appRoot;
91
+ }
92
+ function getToken(appRoot, token) {
93
+ return ((typeof ng === 'object' && ng.getInjector(appRoot).get(token)) || undefined);
94
+ }
95
+ function getApplicationRef(appRoot) {
96
+ const appRef = getToken(appRoot, core_1.ApplicationRef);
97
+ if (!appRef) {
98
+ console.warn(`[NG HMR] Cannot get 'ApplicationRef'.`);
99
+ return undefined;
100
+ }
101
+ return appRef;
102
+ }
103
+ function getPlatformRef(appRoot) {
104
+ const platformRef = getToken(appRoot, core_1.PlatformRef);
105
+ if (!platformRef) {
106
+ console.warn(`[NG HMR] Cannot get 'PlatformRef'.`);
107
+ return undefined;
108
+ }
109
+ return platformRef;
110
+ }
111
+ function dispatchEvents(element) {
112
+ element.dispatchEvent(new Event('input', {
113
+ bubbles: true,
114
+ cancelable: true,
115
+ }));
116
+ element.blur();
117
+ element.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' }));
118
+ }
119
+ function restoreFormValues(oldInputs, oldOptions) {
120
+ // Restore input that are not hidden
121
+ const newInputs = document.querySelectorAll('input:not([type="hidden"]), textarea');
122
+ if (newInputs.length && newInputs.length === oldInputs.length) {
123
+ console.log('[NG HMR] Restoring input/textarea values.');
124
+ for (let index = 0; index < newInputs.length; index++) {
125
+ const newElement = newInputs[index];
126
+ const oldElement = oldInputs[index];
127
+ switch (oldElement.type) {
128
+ case 'button':
129
+ case 'image':
130
+ case 'submit':
131
+ case 'reset':
132
+ // These types don't need any value change.
133
+ continue;
134
+ case 'radio':
135
+ case 'checkbox':
136
+ newElement.checked = oldElement.checked;
137
+ break;
138
+ case 'color':
139
+ case 'date':
140
+ case 'datetime-local':
141
+ case 'email':
142
+ case 'hidden':
143
+ case 'month':
144
+ case 'number':
145
+ case 'password':
146
+ case 'range':
147
+ case 'search':
148
+ case 'tel':
149
+ case 'text':
150
+ case 'textarea':
151
+ case 'time':
152
+ case 'url':
153
+ case 'week':
154
+ newElement.value = oldElement.value;
155
+ break;
156
+ case 'file':
157
+ // Ignored due: Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement':
158
+ // This input element accepts a filename, which may only be programmatically set to the empty string.
159
+ break;
160
+ default:
161
+ console.warn('[NG HMR] Unknown input type ' + oldElement.type + '.');
162
+ continue;
163
+ }
164
+ dispatchEvents(newElement);
165
+ }
166
+ }
167
+ else if (oldInputs.length) {
168
+ console.warn('[NG HMR] Cannot restore input/textarea values.');
169
+ }
170
+ // Restore option
171
+ const newOptions = document.querySelectorAll('option');
172
+ if (newOptions.length && newOptions.length === oldOptions.length) {
173
+ console.log('[NG HMR] Restoring selected options.');
174
+ for (let index = 0; index < newOptions.length; index++) {
175
+ const newElement = newOptions[index];
176
+ newElement.selected = oldOptions[index].selected;
177
+ dispatchEvents(newElement);
178
+ }
179
+ }
180
+ else if (oldOptions.length) {
181
+ console.warn('[NG HMR] Cannot restore selected options.');
182
+ }
183
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ng-rspack.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/ng-rspack.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAIR,oBAAoB,EACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EACV,WAAW,EACX,oCAAoC,EACrC,MAAM,WAAW,CAAC;AAOnB,qBAAa,cAAe,YAAW,oBAAoB;IACzD,QAAQ,CAAC,aAAa,EAAE,oCAAoC,CAAC;IAC7D,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;gBAGzB,aAAa,EAAE,oCAAoC,EACnD,YAAY,EAAE;QACZ,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAC;QAC/B,WAAW,EAAE,WAAW,CAAC;KAC1B;IAOH,KAAK,CAAC,QAAQ,EAAE,QAAQ;CAkHzB"}
1
+ {"version":3,"file":"ng-rspack.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/ng-rspack.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGR,oBAAoB,EACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EACV,WAAW,EACX,oCAAoC,EACrC,MAAM,WAAW,CAAC;AASnB,qBAAa,cAAe,YAAW,oBAAoB;IACzD,QAAQ,CAAC,aAAa,EAAE,oCAAoC,CAAC;IAC7D,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;gBAGzB,aAAa,EAAE,oCAAoC,EACnD,YAAY,EAAE;QACZ,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAC;QAC/B,WAAW,EAAE,WAAW,CAAC;KAC1B;IAOH,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA+IzB"}
@@ -9,6 +9,8 @@ const angular_ssr_dev_server_1 = require("./angular-ssr-dev-server");
9
9
  const i18n_inline_plugin_1 = require("./i18n-inline-plugin");
10
10
  const index_html_plugin_1 = require("./index-html-plugin");
11
11
  const rxjs_esm_resolution_1 = require("./rxjs-esm-resolution");
12
+ const progress_plugin_1 = require("./progress-plugin");
13
+ const misc_helpers_1 = require("../utils/misc-helpers");
12
14
  class NgRspackPlugin {
13
15
  pluginOptions;
14
16
  isPlatformServer;
@@ -28,14 +30,16 @@ class NgRspackPlugin {
28
30
  new angular_ssr_dev_server_1.AngularSsrDevServer(this.pluginOptions).apply(compiler);
29
31
  }
30
32
  }
31
- if (!isDevServer) {
32
- new core_1.ProgressPlugin().apply(compiler);
33
+ if (!isDevServer && this.pluginOptions.progress) {
34
+ new progress_plugin_1.ProgressPlugin(this.isPlatformServer ? 'server' : 'browser').apply(compiler);
33
35
  }
34
36
  new core_1.DefinePlugin({
35
- // TODO: Replace with ...(this.pluginOptions.optimization.scripts ? { 'ngDevMode': 'false' } : undefined) when Optimization is implemented
36
- ...(this.pluginOptions.optimization ? { ngDevMode: 'false' } : {}),
37
+ ...(this.pluginOptions.optimization.scripts
38
+ ? { ngDevMode: 'false' }
39
+ : {}),
37
40
  ngJitMode: this.pluginOptions.aot ? undefined : 'true',
38
41
  ngServerMode: this.isPlatformServer,
42
+ ngHmrMode: this.pluginOptions.devServer?.hmr && isDevServer ? 'true' : 'false',
39
43
  ...(this.pluginOptions.define ?? {}),
40
44
  }).apply(compiler);
41
45
  if (this.pluginOptions.assets) {
@@ -85,8 +89,6 @@ class NgRspackPlugin {
85
89
  new rxjs_esm_resolution_1.RxjsEsmResolutionPlugin().apply(compiler);
86
90
  new angular_rspack_plugin_1.AngularRspackPlugin(this.pluginOptions, this.i18n).apply(compiler);
87
91
  if (!this.isPlatformServer && this.pluginOptions.index) {
88
- // @TODO: remove this once we properly support optimization granular options
89
- const optimize = this.pluginOptions.optimization !== false;
90
92
  new index_html_plugin_1.IndexHtmlPlugin({
91
93
  indexPath: this.pluginOptions.index.input,
92
94
  index: this.pluginOptions.index,
@@ -94,15 +96,7 @@ class NgRspackPlugin {
94
96
  outputPath: this.pluginOptions.outputPath.browser,
95
97
  entrypoints: (0, entry_points_1.getEntryPoints)(this.pluginOptions.globalStyles, this.pluginOptions.globalScripts, this.pluginOptions.devServer?.hmr),
96
98
  i18n: this.i18n,
97
- optimization: {
98
- fonts: { inline: optimize },
99
- scripts: optimize,
100
- styles: {
101
- inlineCritical: optimize,
102
- minify: optimize,
103
- removeSpecialComments: optimize,
104
- },
105
- },
99
+ optimization: this.pluginOptions.optimization,
106
100
  isSsr: !!(this.pluginOptions.ssr ||
107
101
  this.pluginOptions.prerender ||
108
102
  this.pluginOptions.appShell),
@@ -111,6 +105,32 @@ class NgRspackPlugin {
111
105
  sri: this.pluginOptions.subresourceIntegrity,
112
106
  }).apply(compiler);
113
107
  }
108
+ if (this.pluginOptions.devServer.open &&
109
+ isDevServer &&
110
+ !this.isPlatformServer) {
111
+ compiler.hooks.afterEmit.tapAsync('AngularRspackPlugin', async (_, callback) => {
112
+ const protocol = this.pluginOptions.devServer.ssl ? 'https' : 'http';
113
+ const hostname = this.pluginOptions.devServer.host === '0.0.0.0'
114
+ ? 'localhost'
115
+ : this.pluginOptions.devServer.host;
116
+ const port = this.pluginOptions.devServer.port;
117
+ const pathname = typeof compiler.options.devServer?.devMiddleware?.publicPath ===
118
+ 'string'
119
+ ? compiler.options.devServer?.devMiddleware?.publicPath
120
+ : undefined;
121
+ const serverAddress = new URL(`${protocol}://${hostname}:${port}`);
122
+ if (pathname) {
123
+ // Ensure pathname starts with a slash
124
+ serverAddress.pathname = pathname.startsWith('/')
125
+ ? pathname
126
+ : `/${pathname}`;
127
+ }
128
+ const open = (await (0, misc_helpers_1.loadEsmModule)('open'))
129
+ .default;
130
+ await open(serverAddress.toString());
131
+ callback();
132
+ });
133
+ }
114
134
  }
115
135
  }
116
136
  exports.NgRspackPlugin = NgRspackPlugin;
@@ -1 +1 @@
1
- {"version":3,"file":"prerender-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/prerender-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAOhF,OAAO,EACL,KAAK,WAAW,EAEhB,oCAAoC,EACrC,MAAM,WAAW,CAAC;AAenB,qBAAa,eAAgB,YAAW,oBAAoB;;gBAKxD,OAAO,EAAE,oCAAoC,EAC7C,WAAW,CAAC,EAAE,WAAW;IAM3B,KAAK,CAAC,QAAQ,EAAE,QAAQ;CAmLzB"}
1
+ {"version":3,"file":"prerender-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/prerender-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAOhF,OAAO,EACL,KAAK,WAAW,EAEhB,oCAAoC,EACrC,MAAM,WAAW,CAAC;AAenB,qBAAa,eAAgB,YAAW,oBAAoB;;gBAKxD,OAAO,EAAE,oCAAoC,EAC7C,WAAW,CAAC,EAAE,WAAW;IAM3B,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA2QzB"}
@@ -28,11 +28,82 @@ class PrerenderPlugin {
28
28
  }
29
29
  apply(compiler) {
30
30
  compiler.hooks.afterEmit.tapAsync('Angular Rspack', async (compilation, callback) => {
31
- await this.#renderUniversal(compilation);
31
+ if (this.#_options.appShell) {
32
+ await this.#prerenderAppShell(compilation);
33
+ }
34
+ if (this.#_options.prerender) {
35
+ await this.#prerenderSSGUniversal(compilation);
36
+ }
32
37
  callback();
33
38
  });
34
39
  }
35
- async #renderUniversal(compilation) {
40
+ async #prerenderAppShell(compilation) {
41
+ // Users can specify a different base html file e.g. "src/home.html"
42
+ const indexFile = (0, get_index_output_file_1.getIndexOutputFile)(this.#_options.index);
43
+ const zonePackage = require.resolve('zone.js', {
44
+ paths: [devkit_1.workspaceRoot],
45
+ });
46
+ const worker = new worker_pool_1.WorkerPool({
47
+ filename: require.resolve('./tools/render-worker'),
48
+ maxThreads: (0, max_workers_1.maxWorkers)(),
49
+ workerData: {
50
+ zonePackage,
51
+ },
52
+ recordTiming: false,
53
+ });
54
+ try {
55
+ const outputPaths = this.#i18n
56
+ ? (0, i18n_1.ensureOutputPaths)(this.#_options.outputPath.browser, this.#i18n)
57
+ : new Map([['', this.#_options.outputPath.browser]]);
58
+ const localeOutputPaths = this.#i18n
59
+ ? (0, i18n_1.getLocaleOutputPaths)(this.#i18n)
60
+ : new Map();
61
+ for (const [locale, outputPath] of outputPaths.entries()) {
62
+ const normalizedOutputPath = (0, path_1.join)(this.#_options.outputPath.browser, outputPath);
63
+ const serverBundlePath = locale
64
+ ? (0, path_1.join)(this.#_options.outputPath.server, localeOutputPaths.get(locale), 'server.js')
65
+ : (0, path_1.join)(this.#_options.outputPath.server, 'server.js');
66
+ if (!(0, fs_1.existsSync)(serverBundlePath)) {
67
+ throw new Error(`Could not find the main bundle: ${serverBundlePath}`);
68
+ }
69
+ try {
70
+ const options = {
71
+ indexFile,
72
+ deployUrl: this.#_options.deployUrl || '',
73
+ inlineCriticalCss: !!this.#_options.optimization.styles.inlineCritical,
74
+ minifyCss: !!this.#_options.optimization.styles.minify,
75
+ outputPath: normalizedOutputPath,
76
+ route: '/',
77
+ serverBundlePath,
78
+ };
79
+ const { errors, warnings } = await worker.run(options);
80
+ errors?.forEach((e) => (0, rspack_diagnostics_1.addError)(compilation, e));
81
+ warnings?.forEach((e) => (0, rspack_diagnostics_1.addWarning)(compilation, e));
82
+ }
83
+ catch (error) {
84
+ (0, misc_helpers_1.assertIsError)(error);
85
+ (0, rspack_diagnostics_1.addError)(compilation, error.message);
86
+ }
87
+ if (this.#_options.serviceWorker && this.#_options.ngswConfigPath) {
88
+ try {
89
+ await (0, private_1.augmentAppWithServiceWorker)(this.#_options.root, devkit_1.workspaceRoot, outputPath, this.#_options.baseHref || '/', this.#_options.ngswConfigPath);
90
+ }
91
+ catch (error) {
92
+ (0, misc_helpers_1.assertIsError)(error);
93
+ (0, rspack_diagnostics_1.addError)(compilation, error.message);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ catch (error) {
99
+ (0, misc_helpers_1.assertIsError)(error);
100
+ (0, rspack_diagnostics_1.addError)(compilation, error.message);
101
+ }
102
+ finally {
103
+ void worker.destroy();
104
+ }
105
+ }
106
+ async #prerenderSSGUniversal(compilation) {
36
107
  // Users can specify a different base html file e.g. "src/home.html"
37
108
  const indexFile = (0, get_index_output_file_1.getIndexOutputFile)(this.#_options.index);
38
109
  const zonePackage = require.resolve('zone.js', {
@@ -68,14 +139,8 @@ class PrerenderPlugin {
68
139
  const options = {
69
140
  indexFile,
70
141
  deployUrl: this.#_options.deployUrl || '',
71
- inlineCriticalCss:
72
- // TODO: Enable below when styles optimization is enabled
73
- // !!normalizedStylesOptimization.inlineCritical,
74
- true,
75
- minifyCss:
76
- // TODO: Enable below when styles optimization is enabled
77
- // !!normalizedStylesOptimization.minify,
78
- true,
142
+ inlineCriticalCss: !!this.#_options.optimization.styles.inlineCritical,
143
+ minifyCss: !!this.#_options.optimization.styles.minify,
79
144
  outputPath: normalizedOutputPath,
80
145
  route,
81
146
  serverBundlePath,
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.dev/license
7
+ */
8
+ import { ProgressPlugin as RspackProgressPlugin } from '@rspack/core';
9
+ export declare class ProgressPlugin extends RspackProgressPlugin {
10
+ constructor(platform: 'server' | 'browser');
11
+ }
12
+ //# sourceMappingURL=progress-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/progress-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,IAAI,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGtE,qBAAa,cAAe,SAAQ,oBAAoB;gBAC1C,QAAQ,EAAE,QAAQ,GAAG,SAAS;CA6B3C"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.dev/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ProgressPlugin = void 0;
11
+ const core_1 = require("@rspack/core");
12
+ const spinner_1 = require("../utils/spinner");
13
+ class ProgressPlugin extends core_1.ProgressPlugin {
14
+ constructor(platform) {
15
+ const platformCapitalFirst = platform.replace(/^\w/, (s) => s.toUpperCase());
16
+ const spinner = new spinner_1.Spinner();
17
+ spinner.start(`Generating ${platform} application bundles (phase: setup)...`);
18
+ super((percentage, message) => {
19
+ const phase = message ? ` (phase: ${message})` : '';
20
+ spinner.text = `Generating ${platform} application bundles${phase}...`;
21
+ switch (percentage) {
22
+ case 1:
23
+ if (spinner.isSpinning) {
24
+ spinner.succeed(`${platformCapitalFirst} application bundle generation complete.`);
25
+ }
26
+ break;
27
+ case 0:
28
+ if (!spinner.isSpinning) {
29
+ spinner.start();
30
+ }
31
+ break;
32
+ }
33
+ });
34
+ }
35
+ }
36
+ exports.ProgressPlugin = ProgressPlugin;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.dev/license
7
+ */
8
+ import type { RspackPluginInstance, Compiler } from '@rspack/core';
9
+ export declare class StatsJsonPlugin implements RspackPluginInstance {
10
+ private readonly statsOutputPath;
11
+ constructor(statsOutputPath: string);
12
+ apply(compiler: Compiler): void;
13
+ }
14
+ //# sourceMappingURL=stats-json-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats-json-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/stats-json-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAInE,qBAAa,eAAgB,YAAW,oBAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,EAAE,MAAM;IAEpD,KAAK,CAAC,QAAQ,EAAE,QAAQ;CAuBzB"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.dev/license
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.StatsJsonPlugin = void 0;
44
+ const node_fs_1 = require("node:fs");
45
+ const promises_1 = require("node:fs/promises");
46
+ const node_path_1 = require("node:path");
47
+ const promises_2 = require("node:stream/promises");
48
+ const misc_helpers_1 = require("../utils/misc-helpers");
49
+ const rspack_diagnostics_1 = require("../utils/rspack-diagnostics");
50
+ class StatsJsonPlugin {
51
+ statsOutputPath;
52
+ constructor(statsOutputPath) {
53
+ this.statsOutputPath = statsOutputPath;
54
+ }
55
+ apply(compiler) {
56
+ compiler.hooks.done.tapPromise('AngularRspackStatsJsonPlugin', async (stats) => {
57
+ const { stringifyChunked } = await Promise.resolve().then(() => __importStar(require('@discoveryjs/json-ext')));
58
+ const data = stats.toJson('verbose');
59
+ try {
60
+ await (0, promises_1.mkdir)((0, node_path_1.dirname)(this.statsOutputPath), { recursive: true });
61
+ await (0, promises_2.pipeline)(stringifyChunked(data), (0, node_fs_1.createWriteStream)(this.statsOutputPath));
62
+ }
63
+ catch (error) {
64
+ (0, misc_helpers_1.assertIsError)(error);
65
+ (0, rspack_diagnostics_1.addError)(stats.compilation, `Unable to write stats file: ${error.message || 'unknown error'}`);
66
+ }
67
+ });
68
+ }
69
+ }
70
+ exports.StatsJsonPlugin = StatsJsonPlugin;
@@ -0,0 +1,5 @@
1
+ import { Compiler, RspackPluginInstance } from '@rspack/core';
2
+ export declare class SuppressJsForCssOnlyEntryPlugin implements RspackPluginInstance {
3
+ apply(compiler: Compiler): void;
4
+ }
5
+ //# sourceMappingURL=suppress-js-for-css-chunks-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suppress-js-for-css-chunks-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/suppress-js-for-css-chunks-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAgB,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAE5E,qBAAa,+BAAgC,YAAW,oBAAoB;IAC1E,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA6CzB"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SuppressJsForCssOnlyEntryPlugin = void 0;
4
+ class SuppressJsForCssOnlyEntryPlugin {
5
+ apply(compiler) {
6
+ compiler.hooks.thisCompilation.tap('SuppressJsForCssOnlyEntryPlugin', (compilation) => {
7
+ compilation.hooks.processAssets.tap({
8
+ name: 'SuppressJsForCssOnlyEntryPlugin',
9
+ stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
10
+ }, (_) => {
11
+ for (const chunk of compilation.chunks) {
12
+ const cssFiles = [...chunk.files].filter((f) => f.endsWith('.css'));
13
+ const jsFiles = [...chunk.files].filter((f) => f.endsWith('.js'));
14
+ // Only act if chunk has CSS and a single JS file
15
+ if (cssFiles.length > 0 && jsFiles.length === 1) {
16
+ const jsAssetName = jsFiles[0];
17
+ const asset = compilation.getAsset(jsAssetName);
18
+ if (!asset)
19
+ continue;
20
+ const entryModules = compilation.chunkGraph.getChunkEntryModulesIterable(chunk);
21
+ const cssOnly = Array.from(entryModules).every((module) => {
22
+ const extensions = ['.css', '.scss', '.sass', '.less'];
23
+ return extensions.some((ext) => module.resourceResolveData?.path?.endsWith(ext));
24
+ });
25
+ if (cssOnly) {
26
+ compilation.deleteAsset(jsAssetName);
27
+ }
28
+ }
29
+ }
30
+ });
31
+ });
32
+ }
33
+ }
34
+ exports.SuppressJsForCssOnlyEntryPlugin = SuppressJsForCssOnlyEntryPlugin;
@@ -1 +1 @@
1
- {"version":3,"file":"dev-tools-ignore-plugin.d.ts","sourceRoot":"","sources":["../../../../src/lib/plugins/tools/dev-tools-ignore-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAe,QAAQ,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAa3E;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,oBAAoB;IAC/D,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA4CzB"}
1
+ {"version":3,"file":"dev-tools-ignore-plugin.d.ts","sourceRoot":"","sources":["../../../../src/lib/plugins/tools/dev-tools-ignore-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAe,QAAQ,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAa3E;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,oBAAoB;IAC/D,KAAK,CAAC,QAAQ,EAAE,QAAQ;CAgDzB"}
@@ -48,7 +48,7 @@ class DevToolsIgnorePlugin {
48
48
  }
49
49
  }
50
50
  map[IGNORE_LIST] = ignoreList;
51
- compilation.updateAsset(name, new RawSource(JSON.stringify(map)));
51
+ compilation.updateAsset(name, new RawSource(JSON.stringify(map)), (assetInfo) => assetInfo);
52
52
  }
53
53
  });
54
54
  });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.dev/license
7
+ */
8
+ import { Compiler, RspackPluginInstance } from '@rspack/core';
9
+ export declare class TransferSizePlugin implements RspackPluginInstance {
10
+ apply(compiler: Compiler): void;
11
+ }
12
+ //# sourceMappingURL=transfer-size-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-size-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/transfer-size-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAO9D,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA8CzB"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.dev/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.TransferSizePlugin = void 0;
11
+ const node_util_1 = require("node:util");
12
+ const node_zlib_1 = require("node:zlib");
13
+ const rspack_diagnostics_1 = require("../utils/rspack-diagnostics");
14
+ const brotliCompressAsync = (0, node_util_1.promisify)(node_zlib_1.brotliCompress);
15
+ const PLUGIN_NAME = 'angular-transfer-size-estimator';
16
+ class TransferSizePlugin {
17
+ apply(compiler) {
18
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
19
+ compilation.hooks.processAssets.tapAsync({
20
+ name: PLUGIN_NAME,
21
+ stage: compiler.rspack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
22
+ }, async (compilationAssets, callback) => {
23
+ const actions = [];
24
+ for (const assetName of Object.keys(compilationAssets)) {
25
+ if (!assetName.endsWith('.js') && !assetName.endsWith('.css')) {
26
+ continue;
27
+ }
28
+ const scriptAsset = compilation.getAsset(assetName);
29
+ if (!scriptAsset || scriptAsset.source.size() <= 0) {
30
+ continue;
31
+ }
32
+ actions.push(brotliCompressAsync(scriptAsset.source.source())
33
+ .then((result) => {
34
+ compilation.updateAsset(assetName, (s) => s, (assetInfo) => {
35
+ assetInfo.estimatedTransferSize = result.length;
36
+ return assetInfo;
37
+ });
38
+ })
39
+ .catch((error) => {
40
+ (0, rspack_diagnostics_1.addWarning)(compilation, `Unable to calculate estimated transfer size for '${assetName}'. Reason: ${error.message}`);
41
+ }));
42
+ }
43
+ await Promise.all(actions);
44
+ callback();
45
+ });
46
+ });
47
+ }
48
+ }
49
+ exports.TransferSizePlugin = TransferSizePlugin;