Skip to content

Commit 2809971

Browse files
alan-agius4clydin
authored andcommitted
fix(@angular-devkit/build-angular): only generate server directory when SSR is enabled
Previously, the `server` directory was erroneously generated even in instances where SSG was enabled but SSR remained inactive. (cherry picked from commit 6d0ebdb)
1 parent 3f601a1 commit 2809971

File tree

3 files changed

+77
-26
lines changed

3 files changed

+77
-26
lines changed

packages/angular_devkit/build_angular/src/builders/application/build-action.ts

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
import { deleteOutputDir } from '../../utils/delete-output-dir';
2323
import { shouldWatchRoot } from '../../utils/environment-options';
2424
import { NormalizedCachedOptions } from '../../utils/normalize-cache';
25-
import { NormalizedOutputOptions } from './options';
25+
import { NormalizedApplicationBuildOptions, NormalizedOutputOptions } from './options';
2626

2727
// Watch workspace for package manager changes
2828
const packageWatchFiles = [
@@ -38,6 +38,9 @@ const packageWatchFiles = [
3838
'.pnp.data.json',
3939
];
4040

41+
type BuildActionOutput = (ExecutionResult['outputWithFiles'] | ExecutionResult['output']) &
42+
BuilderOutput;
43+
4144
export async function* runEsBuildBuildAction(
4245
action: (rebuildState?: RebuildState) => Promise<ExecutionResult>,
4346
options: {
@@ -59,7 +62,7 @@ export async function* runEsBuildBuildAction(
5962
colors?: boolean;
6063
jsonLogs?: boolean;
6164
},
62-
): AsyncIterable<(ExecutionResult['outputWithFiles'] | ExecutionResult['output']) & BuilderOutput> {
65+
): AsyncIterable<BuildActionOutput> {
6366
const {
6467
writeToFileSystemFilter,
6568
writeToFileSystem,
@@ -154,16 +157,7 @@ export async function* runEsBuildBuildAction(
154157
// Output the first build results after setting up the watcher to ensure that any code executed
155158
// higher in the iterator call stack will trigger the watcher. This is particularly relevant for
156159
// unit tests which execute the builder and modify the file system programmatically.
157-
if (writeToFileSystem) {
158-
// Write output files
159-
await writeResultFiles(result.outputFiles, result.assetFiles, outputOptions);
160-
161-
yield result.output;
162-
} else {
163-
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
164-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
165-
yield result.outputWithFiles as any;
166-
}
160+
yield await writeAndEmitOutput(writeToFileSystem, result, outputOptions, writeToFileSystemFilter);
167161

168162
// Finish if watch mode is not enabled
169163
if (!watcher) {
@@ -213,19 +207,12 @@ export async function* runEsBuildBuildAction(
213207
watcher.remove([...staleWatchFiles]);
214208
}
215209

216-
if (writeToFileSystem) {
217-
// Write output files
218-
const filesToWrite = writeToFileSystemFilter
219-
? result.outputFiles.filter(writeToFileSystemFilter)
220-
: result.outputFiles;
221-
await writeResultFiles(filesToWrite, result.assetFiles, outputOptions);
222-
223-
yield result.output;
224-
} else {
225-
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
226-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
227-
yield result.outputWithFiles as any;
228-
}
210+
yield await writeAndEmitOutput(
211+
writeToFileSystem,
212+
result,
213+
outputOptions,
214+
writeToFileSystemFilter,
215+
);
229216
}
230217
} finally {
231218
// Stop the watcher and cleanup incremental rebuild state
@@ -234,3 +221,25 @@ export async function* runEsBuildBuildAction(
234221
shutdownSassWorkerPool();
235222
}
236223
}
224+
225+
async function writeAndEmitOutput(
226+
writeToFileSystem: boolean,
227+
{ outputFiles, output, outputWithFiles, assetFiles }: ExecutionResult,
228+
outputOptions: NormalizedApplicationBuildOptions['outputOptions'],
229+
writeToFileSystemFilter: ((file: BuildOutputFile) => boolean) | undefined,
230+
): Promise<BuildActionOutput> {
231+
if (writeToFileSystem) {
232+
// Write output files
233+
const outputFilesToWrite = writeToFileSystemFilter
234+
? outputFiles.filter(writeToFileSystemFilter)
235+
: outputFiles;
236+
237+
await writeResultFiles(outputFilesToWrite, assetFiles, outputOptions);
238+
239+
return output;
240+
} else {
241+
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
242+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
243+
return outputWithFiles as any;
244+
}
245+
}

packages/angular_devkit/build_angular/src/builders/application/tests/options/ssr_spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,47 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
5050
expect(result?.success).toBeTrue();
5151
harness.expectFile('dist/server/server.mjs').toExist();
5252
});
53+
54+
it(`should emit 'server' directory when 'ssr' is 'true'`, async () => {
55+
await harness.writeFile('file.mjs', `console.log('Hello!');`);
56+
57+
harness.useTarget('build', {
58+
...BASE_OPTIONS,
59+
server: 'src/main.server.ts',
60+
ssr: true,
61+
});
62+
63+
const { result } = await harness.executeOnce();
64+
expect(result?.success).toBeTrue();
65+
harness.expectDirectory('dist/server').toExist();
66+
});
67+
68+
it(`should not emit 'server' directory when 'ssr' is 'false'`, async () => {
69+
await harness.writeFile('file.mjs', `console.log('Hello!');`);
70+
71+
harness.useTarget('build', {
72+
...BASE_OPTIONS,
73+
server: 'src/main.server.ts',
74+
ssr: false,
75+
});
76+
77+
const { result } = await harness.executeOnce();
78+
expect(result?.success).toBeTrue();
79+
harness.expectDirectory('dist/server').toNotExist();
80+
});
81+
82+
it(`should not emit 'server' directory when 'ssr' is not set`, async () => {
83+
await harness.writeFile('file.mjs', `console.log('Hello!');`);
84+
85+
harness.useTarget('build', {
86+
...BASE_OPTIONS,
87+
server: 'src/main.server.ts',
88+
ssr: undefined,
89+
});
90+
91+
const { result } = await harness.executeOnce();
92+
expect(result?.success).toBeTrue();
93+
harness.expectDirectory('dist/server').toNotExist();
94+
});
5395
});
5496
});

packages/angular_devkit/build_angular/src/tools/esbuild/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ export function getFeatureSupport(target: string[]): BuildOptions['supported'] {
217217
export async function writeResultFiles(
218218
outputFiles: BuildOutputFile[],
219219
assetFiles: BuildOutputAsset[] | undefined,
220-
{ base, browser, media, server }: NormalizedOutputOptions,
220+
{ base, browser, server }: NormalizedOutputOptions,
221221
) {
222222
const directoryExists = new Set<string>();
223223
const ensureDirectoryExists = async (destPath: string) => {

0 commit comments

Comments
 (0)