Skip to content

Commit 5e6f1a9

Browse files
committed
fix(@angular-devkit/build-angular): avoid preloading server chunks
41ea985#diff-239ad7beb7d8a76046cdc7b4d2263b2e05c300e3e0510916cb907e93efec5af0 introduced a regression which causes server enter-points
1 parent ccdaed4 commit 5e6f1a9

File tree

3 files changed

+49
-12
lines changed

3 files changed

+49
-12
lines changed

packages/angular_devkit/build_angular/src/builders/application/tests/behavior/index-preload-hints_spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,32 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
3333
'<link rel="preload" href="https://fonts.googleapis.com/css2?family=Roboto+Mono&family=Roboto:wght@300;400;500;700&display=swap" as="style">',
3434
);
3535
});
36+
37+
it('should not add preload hints for ssr files', async () => {
38+
await harness.modifyFile('src/tsconfig.app.json', (content) => {
39+
const tsConfig = JSON.parse(content);
40+
tsConfig.files ??= [];
41+
tsConfig.files.push('main.server.ts', 'server.ts');
42+
43+
return JSON.stringify(tsConfig);
44+
});
45+
46+
await harness.writeFile('src/server.ts', `console.log('Hello!');`);
47+
48+
harness.useTarget('build', {
49+
...BASE_OPTIONS,
50+
server: 'src/main.server.ts',
51+
ssr: true,
52+
});
53+
54+
const { result } = await harness.executeOnce();
55+
expect(result?.success).toBeTrue();
56+
57+
harness.expectFile('dist/server/main.server.mjs').toExist();
58+
59+
harness
60+
.expectFile('dist/browser/index.html')
61+
.content.not.toMatch(/<link rel="modulepreload" href="chunk-\.+\.mjs">/);
62+
});
3663
});
3764
});

packages/angular_devkit/build_angular/src/tools/esbuild/bundler-context.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export interface InitialFileRecord {
4242
name?: string;
4343
type: 'script' | 'style';
4444
external?: boolean;
45+
serverFile: boolean;
4546
}
4647

4748
export enum BuildOutputFileType {
@@ -75,7 +76,6 @@ export class BundlerContext {
7576
#esbuildResult?: BundleContextResult;
7677
#optionsFactory: BundlerOptionsFactory<BuildOptions & { metafile: true; write: false }>;
7778
#shouldCacheResult: boolean;
78-
7979
#loadCache?: MemoryLoadResultCache;
8080
readonly watchFiles = new Set<string>();
8181

@@ -222,7 +222,7 @@ export class BundlerContext {
222222
result = await build(this.#esbuildOptions);
223223
}
224224

225-
if (this.#esbuildOptions?.platform === 'node') {
225+
if (this.#platformIsServer) {
226226
for (const entry of Object.values(result.metafile.outputs)) {
227227
// eslint-disable-next-line @typescript-eslint/no-explicit-any
228228
(entry as any)['ng-platform-server'] = true;
@@ -297,6 +297,7 @@ export class BundlerContext {
297297
name,
298298
type,
299299
entrypoint: true,
300+
serverFile: this.#platformIsServer,
300301
};
301302

302303
if (!this.initialFilter || this.initialFilter(record)) {
@@ -319,6 +320,7 @@ export class BundlerContext {
319320
type: initialImport.kind === 'import-rule' ? 'style' : 'script',
320321
entrypoint: false,
321322
external: initialImport.external,
323+
serverFile: this.#platformIsServer,
322324
};
323325

324326
if (!this.initialFilter || this.initialFilter(record)) {
@@ -350,15 +352,16 @@ export class BundlerContext {
350352

351353
assert(this.#esbuildOptions, 'esbuild options cannot be undefined.');
352354

353-
const { platform, assetNames = '' } = this.#esbuildOptions;
354-
const platformIsServer = platform === 'node';
355+
const { assetNames = '' } = this.#esbuildOptions;
355356
const mediaDirname = dirname(assetNames);
356357
const outputFiles = result.outputFiles.map((file) => {
357358
let fileType: BuildOutputFileType;
358359
if (dirname(file.path) === mediaDirname) {
359360
fileType = BuildOutputFileType.Media;
360361
} else {
361-
fileType = platformIsServer ? BuildOutputFileType.Server : BuildOutputFileType.Browser;
362+
fileType = this.#platformIsServer
363+
? BuildOutputFileType.Server
364+
: BuildOutputFileType.Browser;
362365
}
363366

364367
return convertOutputFile(file, fileType);
@@ -370,7 +373,7 @@ export class BundlerContext {
370373
outputFiles,
371374
initialFiles,
372375
externalImports: {
373-
[platformIsServer ? 'server' : 'browser']: externalImports,
376+
[this.#platformIsServer ? 'server' : 'browser']: externalImports,
374377
},
375378
externalConfiguration: this.#esbuildOptions.external,
376379
errors: undefined,
@@ -392,6 +395,10 @@ export class BundlerContext {
392395
}
393396
}
394397

398+
get #platformIsServer(): boolean {
399+
return this.#esbuildOptions?.platform === 'node';
400+
}
401+
395402
/**
396403
* Invalidate a stored bundler result based on the previous watch files
397404
* and a list of changed files.

packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ export async function generateIndexHtml(
4040

4141
if (!externalPackages && indexHtmlOptions.preloadInitial) {
4242
for (const [key, value] of initialFiles) {
43-
if (value.entrypoint) {
43+
if (value.entrypoint || value.serverFile) {
4444
// Entry points are already referenced in the HTML
4545
continue;
4646
}
47+
4748
if (value.type === 'script') {
4849
hints.push({ url: key, mode: 'modulepreload' as const });
4950
} else if (value.type === 'style') {
@@ -91,11 +92,13 @@ export async function generateIndexHtml(
9192
baseHref,
9293
lang,
9394
outputPath: virtualOutputPath,
94-
files: [...initialFiles].map(([file, record]) => ({
95-
name: record.name ?? '',
96-
file,
97-
extension: path.extname(file),
98-
})),
95+
files: [...initialFiles]
96+
.filter(([, file]) => !file.serverFile)
97+
.map(([file, record]) => ({
98+
name: record.name ?? '',
99+
file,
100+
extension: path.extname(file),
101+
})),
99102
hints,
100103
});
101104

0 commit comments

Comments
 (0)