Skip to content

Commit fb99c3e

Browse files
Chlebamaticontenchleb
authored andcommitted
feat(angular-rspack): Add "zoneless" option to enable Angular's provideZonelessChangeDetection() usage (#115)
* feat(angular-rspack): add "zoneless" option to disable zone.js initialization within PrerenderPlugin * test: add e2e fixture for zoneless CSR with CSS spec * test: add e2e fixture for zoneless CSR (i18n) with CSS spec * test: add e2e fixture for zoneless SSG with CSS spec * test: add e2e fixture for zoneless SSR with CSS spec * fix: update import format * fix: replace zoneless property, inferring zone.js polyfill presence instead * fix: update pnpm-lock.yaml --------- Co-authored-by: Jakub Chlebowicz <contact@jakubchlebowicz.com>
1 parent 73b26bc commit fb99c3e

5 files changed

Lines changed: 22 additions & 15 deletions

File tree

packages/angular-rspack/src/lib/models/angular-rspack-plugin-options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,4 +379,5 @@ export interface NormalizedAngularRspackPluginOptions
379379
tsConfig: string;
380380
vendorChunk: boolean;
381381
watch: boolean;
382+
zoneless: boolean;
382383
}

packages/angular-rspack/src/lib/models/normalize-options.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ export async function normalizeOptions(
216216
type: budget.type as any,
217217
}));
218218

219+
const zoneless = options.polyfills
220+
? !options.polyfills.includes('zone.js')
221+
: true;
222+
219223
const stylePreprocessorOptions = options.stylePreprocessorOptions ?? {};
220224
if (stylePreprocessorOptions.includePaths?.length) {
221225
stylePreprocessorOptions.includePaths = [
@@ -273,6 +277,7 @@ export async function normalizeOptions(
273277
vendorChunk: options.vendorChunk ?? false,
274278
verbose: options.verbose ?? false,
275279
watch: options.watch ?? false,
280+
zoneless,
276281
};
277282
}
278283

packages/angular-rspack/src/lib/plugins/prerender-plugin.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,11 @@ export class PrerenderPlugin implements RspackPluginInstance {
5757
this.#_options.index as IndexExpandedDefinition
5858
);
5959

60-
const zonePackage = require.resolve('zone.js', {
61-
paths: [workspaceRoot],
62-
});
63-
6460
const worker = new WorkerPool({
6561
filename: require.resolve('./tools/render-worker'),
6662
maxThreads: maxWorkers(),
6763
workerData: {
68-
zonePackage,
64+
zonePackage: this.#resolveZonePackage(workspaceRoot),
6965
},
7066
recordTiming: false,
7167
});
@@ -145,15 +141,11 @@ export class PrerenderPlugin implements RspackPluginInstance {
145141
this.#_options.index as IndexExpandedDefinition
146142
);
147143

148-
const zonePackage = require.resolve('zone.js', {
149-
paths: [workspaceRoot],
150-
});
151-
152144
const worker = new WorkerPool({
153145
filename: require.resolve('./tools/render-worker'),
154146
maxThreads: maxWorkers(),
155147
workerData: {
156-
zonePackage,
148+
zonePackage: this.#resolveZonePackage(workspaceRoot),
157149
},
158150
recordTiming: false,
159151
});
@@ -270,7 +262,7 @@ export class PrerenderPlugin implements RspackPluginInstance {
270262
indexFile,
271263
outputPath,
272264
serverBundlePath,
273-
zonePackage: require.resolve('zone.js', { paths: [workspaceRoot] }),
265+
zonePackage: this.#resolveZonePackage(workspaceRoot),
274266
},
275267
recordTiming: false,
276268
});
@@ -303,4 +295,9 @@ export class PrerenderPlugin implements RspackPluginInstance {
303295

304296
return this.#_options.prerender;
305297
}
298+
299+
#resolveZonePackage(workspaceRoot: string): string | false {
300+
if (this.#_options.zoneless) return false;
301+
return require.resolve('zone.js', { paths: [workspaceRoot] });
302+
}
306303
}

packages/angular-rspack/src/lib/plugins/tools/render-worker.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ interface ServerBundleExports {
5454
* This is passed as workerData when setting up the worker via the `piscina` package.
5555
*/
5656
const { zonePackage } = workerData as {
57-
zonePackage: string;
57+
zonePackage: string | false;
5858
};
5959

6060
/**
@@ -182,7 +182,9 @@ function isBootstrapFn(value: unknown): value is () => Promise<ApplicationRef> {
182182
*/
183183
async function initialize() {
184184
// Setup Zone.js
185-
await import(zonePackage);
185+
if (zonePackage) {
186+
await import(zonePackage);
187+
}
186188

187189
// Return the render function for use
188190
return render;

packages/angular-rspack/src/lib/plugins/tools/routes-extractor-worker.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import * as path from 'node:path';
1414
import { workerData } from 'node:worker_threads';
1515

1616
export interface RoutesExtractorWorkerData {
17-
zonePackage: string;
17+
zonePackage: string | false;
1818
indexFile: string;
1919
outputPath: string;
2020
serverBundlePath: string;
@@ -74,7 +74,9 @@ async function extract(): Promise<string[]> {
7474
*/
7575
async function initialize() {
7676
// Setup Zone.js
77-
await import(zonePackage);
77+
if (zonePackage) {
78+
await import(zonePackage);
79+
}
7880

7981
return extract;
8082
}

0 commit comments

Comments
 (0)