From b6d81ea0f9b6b9979f7ff4d61ef7fa349d424918 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:37:58 +0000 Subject: [PATCH] fix(@angular/build): failed to proxy error for assets Remove proxy to handle `/` to `/base/` instead update the `AngularAssetsMiddleware` Closes #30639 --- .../src/builders/karma/application_builder.ts | 12 ++- .../angular/build/src/builders/karma/index.ts | 3 - .../karma/tests/options/scripts_spec.ts | 74 +++++++++++++++++++ 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 packages/angular/build/src/builders/karma/tests/options/scripts_spec.ts diff --git a/packages/angular/build/src/builders/karma/application_builder.ts b/packages/angular/build/src/builders/karma/application_builder.ts index d33469a45ef6..3dd968006684 100644 --- a/packages/angular/build/src/builders/karma/application_builder.ts +++ b/packages/angular/build/src/builders/karma/application_builder.ts @@ -84,13 +84,22 @@ class AngularAssetsMiddleware { return; } + // Implementation of serverFile can be found here: + // https://github.com/karma-runner/karma/blob/84f85e7016efc2266fa6b3465f494a3fa151c85c/lib/middleware/common.js#L10 switch (file.origin) { case 'disk': this.serveFile(file.inputPath, undefined, res, undefined, undefined, /* doNotCache */ true); break; case 'memory': // Include pathname to help with Content-Type headers. - this.serveFile(`/unused/${url.pathname}`, undefined, res, undefined, file.contents, true); + this.serveFile( + `/unused/${url.pathname}`, + undefined, + res, + undefined, + file.contents, + /* doNotCache */ false, + ); break; } } @@ -508,6 +517,7 @@ async function initializeApplication( scriptsFiles.push({ pattern: `${outputPath}/${outputName}`, watched: false, + included: typeof scriptEntry === 'string' ? true : scriptEntry.inject !== false, type: 'js', }); } diff --git a/packages/angular/build/src/builders/karma/index.ts b/packages/angular/build/src/builders/karma/index.ts index d3aefeeff628..036d503cfdf6 100644 --- a/packages/angular/build/src/builders/karma/index.ts +++ b/packages/angular/build/src/builders/karma/index.ts @@ -107,9 +107,6 @@ function getBuiltInKarmaConfig( 'karma-jasmine-html-reporter', 'karma-coverage', ].map((p) => workspaceRootRequire(p)), - proxies: { - '/': '/base/', - }, jasmineHtmlReporter: { suppressAll: true, // removes the duplicated traces }, diff --git a/packages/angular/build/src/builders/karma/tests/options/scripts_spec.ts b/packages/angular/build/src/builders/karma/tests/options/scripts_spec.ts new file mode 100644 index 000000000000..483a05929e1c --- /dev/null +++ b/packages/angular/build/src/builders/karma/tests/options/scripts_spec.ts @@ -0,0 +1,74 @@ +/** + * @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.dev/license + */ + +import { execute } from '../../index'; +import { BASE_OPTIONS, KARMA_BUILDER_INFO, describeKarmaBuilder } from '../setup'; + +describeKarmaBuilder(execute, KARMA_BUILDER_INFO, (harness, setupTarget) => { + describe('Option: "scripts"', () => { + beforeEach(async () => { + await setupTarget(harness); + }); + + it(`should be able to access non injected script`, async () => { + await harness.writeFiles({ + 'src/test.js': `console.log('hello from test script.')`, + 'src/app/app.component.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'app-root', + standalone: false, + template: '

Hello World

' + }) + export class AppComponent { + loadScript() { + return new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.onload = () => resolve(); + script.onerror = reject; + script.src = 'test.js'; + document.body.appendChild(script); + }); + } + } + `, + 'src/app/app.component.spec.ts': ` + import { TestBed } from '@angular/core/testing'; + import { AppComponent } from './app.component'; + + describe('AppComponent', () => { + beforeEach(() => TestBed.configureTestingModule({ + declarations: [AppComponent] + })); + + it('should load script', async () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + + await expectAsync(fixture.componentInstance.loadScript()).toBeResolved(); + }); + });`, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + scripts: [ + { + input: 'src/test.js', + bundleName: 'test', + inject: false, + }, + ], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + }); +});