Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): only generate server directory …
Browse files Browse the repository at this point in the history
…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)
  • Loading branch information
alan-agius4 authored and clydin committed Mar 19, 2024
1 parent 3f601a1 commit 2809971
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 26 deletions.
Expand Up @@ -22,7 +22,7 @@ import {
import { deleteOutputDir } from '../../utils/delete-output-dir';
import { shouldWatchRoot } from '../../utils/environment-options';
import { NormalizedCachedOptions } from '../../utils/normalize-cache';
import { NormalizedOutputOptions } from './options';
import { NormalizedApplicationBuildOptions, NormalizedOutputOptions } from './options';

// Watch workspace for package manager changes
const packageWatchFiles = [
Expand All @@ -38,6 +38,9 @@ const packageWatchFiles = [
'.pnp.data.json',
];

type BuildActionOutput = (ExecutionResult['outputWithFiles'] | ExecutionResult['output']) &
BuilderOutput;

export async function* runEsBuildBuildAction(
action: (rebuildState?: RebuildState) => Promise<ExecutionResult>,
options: {
Expand All @@ -59,7 +62,7 @@ export async function* runEsBuildBuildAction(
colors?: boolean;
jsonLogs?: boolean;
},
): AsyncIterable<(ExecutionResult['outputWithFiles'] | ExecutionResult['output']) & BuilderOutput> {
): AsyncIterable<BuildActionOutput> {
const {
writeToFileSystemFilter,
writeToFileSystem,
Expand Down Expand Up @@ -154,16 +157,7 @@ export async function* runEsBuildBuildAction(
// Output the first build results after setting up the watcher to ensure that any code executed
// higher in the iterator call stack will trigger the watcher. This is particularly relevant for
// unit tests which execute the builder and modify the file system programmatically.
if (writeToFileSystem) {
// Write output files
await writeResultFiles(result.outputFiles, result.assetFiles, outputOptions);

yield result.output;
} else {
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
yield result.outputWithFiles as any;
}
yield await writeAndEmitOutput(writeToFileSystem, result, outputOptions, writeToFileSystemFilter);

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

if (writeToFileSystem) {
// Write output files
const filesToWrite = writeToFileSystemFilter
? result.outputFiles.filter(writeToFileSystemFilter)
: result.outputFiles;
await writeResultFiles(filesToWrite, result.assetFiles, outputOptions);

yield result.output;
} else {
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
yield result.outputWithFiles as any;
}
yield await writeAndEmitOutput(
writeToFileSystem,
result,
outputOptions,
writeToFileSystemFilter,
);
}
} finally {
// Stop the watcher and cleanup incremental rebuild state
Expand All @@ -234,3 +221,25 @@ export async function* runEsBuildBuildAction(
shutdownSassWorkerPool();
}
}

async function writeAndEmitOutput(
writeToFileSystem: boolean,
{ outputFiles, output, outputWithFiles, assetFiles }: ExecutionResult,
outputOptions: NormalizedApplicationBuildOptions['outputOptions'],
writeToFileSystemFilter: ((file: BuildOutputFile) => boolean) | undefined,
): Promise<BuildActionOutput> {
if (writeToFileSystem) {
// Write output files
const outputFilesToWrite = writeToFileSystemFilter
? outputFiles.filter(writeToFileSystemFilter)
: outputFiles;

await writeResultFiles(outputFilesToWrite, assetFiles, outputOptions);

return output;
} else {
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return outputWithFiles as any;
}
}
Expand Up @@ -50,5 +50,47 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
expect(result?.success).toBeTrue();
harness.expectFile('dist/server/server.mjs').toExist();
});

it(`should emit 'server' directory when 'ssr' is 'true'`, async () => {
await harness.writeFile('file.mjs', `console.log('Hello!');`);

harness.useTarget('build', {
...BASE_OPTIONS,
server: 'src/main.server.ts',
ssr: true,
});

const { result } = await harness.executeOnce();
expect(result?.success).toBeTrue();
harness.expectDirectory('dist/server').toExist();
});

it(`should not emit 'server' directory when 'ssr' is 'false'`, async () => {
await harness.writeFile('file.mjs', `console.log('Hello!');`);

harness.useTarget('build', {
...BASE_OPTIONS,
server: 'src/main.server.ts',
ssr: false,
});

const { result } = await harness.executeOnce();
expect(result?.success).toBeTrue();
harness.expectDirectory('dist/server').toNotExist();
});

it(`should not emit 'server' directory when 'ssr' is not set`, async () => {
await harness.writeFile('file.mjs', `console.log('Hello!');`);

harness.useTarget('build', {
...BASE_OPTIONS,
server: 'src/main.server.ts',
ssr: undefined,
});

const { result } = await harness.executeOnce();
expect(result?.success).toBeTrue();
harness.expectDirectory('dist/server').toNotExist();
});
});
});
Expand Up @@ -217,7 +217,7 @@ export function getFeatureSupport(target: string[]): BuildOptions['supported'] {
export async function writeResultFiles(
outputFiles: BuildOutputFile[],
assetFiles: BuildOutputAsset[] | undefined,
{ base, browser, media, server }: NormalizedOutputOptions,
{ base, browser, server }: NormalizedOutputOptions,
) {
const directoryExists = new Set<string>();
const ensureDirectoryExists = async (destPath: string) => {
Expand Down

0 comments on commit 2809971

Please sign in to comment.