Skip to content

Commit f30fd9f

Browse files
committed
fix: handle Angular 20+ missing outputPath in deploy action
Angular 20+ omits outputPath from angular.json. When undefined, use the default path: dist/<project-name>/browser. Fixes #199
1 parent d6a00e1 commit f30fd9f

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

src/deploy/actions.spec.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,24 @@ describe('Deploy Angular apps', () => {
8686
).rejects.toThrow('Error while building the app.');
8787
});
8888

89-
it('throws if outputPath is missing from build options', async () => {
89+
it('uses default path when outputPath is undefined (Angular 20+)', async () => {
90+
// Angular 20+ omits outputPath, uses default: dist/<project>/browser
91+
let capturedDir: string | null = null;
92+
93+
const mockEngineWithCapture: EngineHost = {
94+
run: (dir: string, _options: Schema, _logger: logging.LoggerApi) => {
95+
capturedDir = dir;
96+
return Promise.resolve();
97+
}
98+
};
99+
90100
context.getTargetOptions = (_: Target) =>
91101
Promise.resolve({} as JsonObject);
92102

93-
const expectedErrorMessage = `Cannot read the outputPath option of the Angular project '${BUILD_TARGET.name}' in angular.json.`;
103+
await deploy(mockEngineWithCapture, context, BUILD_TARGET, { noBuild: false });
94104

95-
await expect(
96-
deploy(mockEngine, context, BUILD_TARGET, { noBuild: false })
97-
).rejects.toThrow(expectedErrorMessage);
105+
// Default path is dist/<project-name>/browser
106+
expect(capturedDir).toBe(`dist/${PROJECT}/browser`);
98107
});
99108

100109
it('throws if outputPath has invalid shape (not string or object)', async () => {

src/deploy/actions.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,21 @@ export default async function deploy(
6060
);
6161

6262
// Output path configuration
63-
// The outputPath option can be either
63+
// The outputPath option can be either:
64+
// - undefined (Angular 20+): uses default dist/<project-name>/browser
6465
// - a String which will be used as the base value + default value 'browser'
6566
// - or an Object for more fine-tune configuration.
6667
// see https://angular.io/guide/workspace-config#output-path-configuration
6768
// see https://github.com/angular/angular-cli/pull/26675
6869

69-
if (!buildOptions.outputPath) {
70-
throw new Error(
71-
`Cannot read the outputPath option of the Angular project '${buildTarget.name}' in angular.json.`
72-
);
73-
}
74-
75-
const outputPath = buildOptions.outputPath as AngularOutputPath;
70+
const outputPath = buildOptions.outputPath as AngularOutputPath | undefined;
7671

77-
if (typeof outputPath === 'string') {
72+
if (outputPath === undefined) {
73+
// Angular 20+ default: dist/<project-name>/browser
74+
// Extract project name from buildTarget.name (format: "project:target:configuration")
75+
const projectName = buildTarget.name.split(':')[0];
76+
dir = path.join('dist', projectName, 'browser');
77+
} else if (typeof outputPath === 'string') {
7878
dir = path.join(outputPath, 'browser');
7979
} else if (isOutputPathObject(outputPath)) {
8080
dir = path.join(outputPath.base, outputPath.browser ?? '');

0 commit comments

Comments
 (0)