Skip to content

Commit 2b9c00f

Browse files
committed
fix(@angular/build): prevent fallback to serving main.js for unknown requests
Previously, when an unknown `main.js` file was requested, the system would automatically fall back to serving the default `main.js`. This behavior could cause unexpected issues, such as incorrect resource loading or misleading errors. This fix ensures that only valid `main.js` files are served, preventing unintended fallbacks and improving request handling. Closes #29524 (cherry picked from commit 9a46be8)
1 parent 5a6f853 commit 2b9c00f

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
142142
expect(await response?.headers.get('Location')).toBe('/login/');
143143
});
144144

145-
it('serves a JavaScript asset named as a bundle', async () => {
145+
it('serves a JavaScript asset named as a bundle (main.js)', async () => {
146146
await harness.writeFile('public/test/main.js', javascriptFileContent);
147147

148148
setupTarget(harness, {
@@ -162,5 +162,17 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
162162
expect(result?.success).toBeTrue();
163163
expect(await response?.text()).toContain(javascriptFileContent);
164164
});
165+
166+
it('should return 404 when a JavaScript asset named as a bundle (main.js) does not exist', async () => {
167+
setupTarget(harness, {});
168+
169+
harness.useTarget('serve', {
170+
...BASE_OPTIONS,
171+
});
172+
173+
const { result, response } = await executeOnceAndFetch(harness, 'unknown/main.js');
174+
expect(result?.success).toBeTrue();
175+
expect(response?.status).toBe(404);
176+
});
165177
});
166178
});

packages/angular/build/src/builders/dev-server/vite-server.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,11 @@ export async function setupServer(
808808
},
809809
// This is needed when `externalDependencies` is used to prevent Vite load errors.
810810
// NOTE: If Vite adds direct support for externals, this can be removed.
811-
preTransformRequests: externalMetadata.explicitBrowser.length === 0,
811+
// NOTE: Vite breaks the resolution of browser modules in SSR
812+
// when accessing a url with two or more segments (e.g., 'foo/bar'),
813+
// as they are not re-based from the base href.
814+
preTransformRequests:
815+
externalMetadata.explicitBrowser.length === 0 && ssrMode === ServerSsrMode.NoSsr,
812816
},
813817
ssr: {
814818
// Note: `true` and `/.*/` have different sematics. When true, the `external` option is ignored.

packages/angular/build/src/tools/vite/plugins/angular-memory-plugin.ts

+2-14
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,12 @@ export async function createAngularMemoryPlugin(
6262
return source;
6363
}
6464

65-
if (importer) {
65+
if (importer && source[0] === '.') {
6666
const normalizedImporter = normalizePath(importer);
67-
if (source[0] === '.' && normalizedImporter.startsWith(virtualProjectRoot)) {
67+
if (normalizedImporter.startsWith(virtualProjectRoot)) {
6868
// Remove query if present
6969
const [importerFile] = normalizedImporter.split('?', 1);
7070
source = '/' + join(dirname(relative(virtualProjectRoot, importerFile)), source);
71-
} else if (
72-
!ssr &&
73-
source[0] === '/' &&
74-
importer.endsWith('index.html') &&
75-
normalizedImporter.startsWith(virtualProjectRoot)
76-
) {
77-
// This is only needed when using SSR and `angularSsrMiddleware` (old style) to correctly resolve
78-
// .js files when using lazy-loading.
79-
// Remove query if present
80-
const [importerFile] = normalizedImporter.split('?', 1);
81-
source =
82-
'/' + join(dirname(relative(virtualProjectRoot, importerFile)), basename(source));
8371
}
8472
}
8573

0 commit comments

Comments
 (0)