From 3df3e583c8788511598bbe406012196a2882ee49 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 8 Dec 2023 09:57:58 +0000 Subject: [PATCH] fix(@angular-devkit/build-angular): `baseHref` with trailing slash causes server not to be accessible without trailing slash This commit fixes an issue were when using a `baseHref` with trailing slash, vite dev-server would have been only accessible via a URL with a trailing slash. As vite would redirect to an error page similar to the below; ``` The server is configured with a public base URL of /myapp/ - did you mean to visit [/myapp/](http://localhost:4200/myapp/) instead? ``` Closes: #26618 (cherry picked from commit 4b3a965429bfaa6559693b2a3b69565455a75866) --- .../tests/behavior/build-base-href_spec.ts | 49 +++++++++++++++++++ .../src/builders/dev-server/vite-server.ts | 9 ++-- 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/build-base-href_spec.ts diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/build-base-href_spec.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/build-base-href_spec.ts new file mode 100644 index 000000000000..a8063c10ae12 --- /dev/null +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/build-base-href_spec.ts @@ -0,0 +1,49 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import { executeDevServer } from '../../index'; +import { executeOnceAndFetch } from '../execute-fetch'; +import { describeServeBuilder } from '../jasmine-helpers'; +import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup'; + +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + describe('Behavior: "buildTarget baseHref"', () => { + beforeEach(async () => { + setupTarget(harness, { + baseHref: '/test/', + }); + + // Application code is not needed for these tests + await harness.writeFile('src/main.ts', 'console.log("foo");'); + }); + + it('uses the baseHref defined in the "buildTarget" options as the serve path', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/test/main.js'); + + expect(result?.success).toBeTrue(); + const baseUrl = new URL(`${result?.baseUrl}/`); + expect(baseUrl.pathname).toBe('/test/'); + expect(await response?.text()).toContain('console.log'); + }); + + it('serves the application from baseHref location without trailing slash', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/test'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain('