From 76708a17be5ee1b56f2c0159cc6c850570f48b59 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:38:39 +0000 Subject: [PATCH 1/2] fix(@angular/build): serve extensionless assets without transformation Extensionless files are now served directly without being processed by the underlying transformation pipeline. This ensures that such assets are delivered unmodified and prevents potential serving errors. Closes #32560 --- .../tests/behavior/build-assets_spec.ts | 20 +++++++++++++++++++ .../vite/middlewares/assets-middleware.ts | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts index f7c7a0acb33a..7d3e1ffc414b 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts @@ -21,6 +21,26 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT "import {foo} from 'unresolved'; /* a comment */const foo = `bar`;\n\n\n"; describe('Behavior: "browser builder assets"', () => { + it('serves a project extensionless asset unmodified', async () => { + await harness.writeFile('src/extensionless', javascriptFileContent); + + setupTarget(harness, { + assets: ['src/extensionless'], + optimization: { + scripts: true, + }, + }); + + harness.useTarget('serve', { + ...BASE_OPTIONS, + }); + + const { result, response } = await executeOnceAndFetch(harness, 'extensionless'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain(javascriptFileContent); + }); + it('serves a project JavaScript asset unmodified', async () => { await harness.writeFile('src/extra.js', javascriptFileContent); diff --git a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts index f0a137f578f8..455f8120ab50 100644 --- a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts @@ -45,8 +45,8 @@ export function createAngularAssetsMiddleware( // Rewrite all build assets to a vite raw fs URL const asset = assets.get(pathname); if (asset) { - // This is a workaround to serve CSS, JS and TS files without Vite transformations. - if (JS_TS_REGEXP.test(extension) || CSS_PREPROCESSOR_REGEXP.test(extension)) { + // This is a workaround to serve extensionless, CSS, JS and TS files without Vite transformations. + if (!extension || !JS_TS_REGEXP.test(extension) || CSS_PREPROCESSOR_REGEXP.test(extension)) { const contents = readFileSync(asset.source); const etag = `W/${createHash('sha256').update(contents).digest('hex')}`; if (checkAndHandleEtag(req, res, etag)) { From 81a015bdec422ba637a16e6161fc0fe7db600446 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 24 Feb 2026 13:07:36 +0100 Subject: [PATCH 2/2] fixup! fix(@angular/build): serve extensionless assets without transformation --- .../build/src/tools/vite/middlewares/assets-middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts index 455f8120ab50..e0074625afe0 100644 --- a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts @@ -46,7 +46,7 @@ export function createAngularAssetsMiddleware( const asset = assets.get(pathname); if (asset) { // This is a workaround to serve extensionless, CSS, JS and TS files without Vite transformations. - if (!extension || !JS_TS_REGEXP.test(extension) || CSS_PREPROCESSOR_REGEXP.test(extension)) { + if (!extension || JS_TS_REGEXP.test(extension) || CSS_PREPROCESSOR_REGEXP.test(extension)) { const contents = readFileSync(asset.source); const etag = `W/${createHash('sha256').update(contents).digest('hex')}`; if (checkAndHandleEtag(req, res, etag)) {