Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): ensure correct .html served wit…
Browse files Browse the repository at this point in the history
…h Vite dev-server

Prior to this commit, the Vite html fallback middleware failed to handle the in-memory assets generated by Angular CLI, resulting in incorrect fallback behavior. For instance, when an `index.html` existed as an asset under a specific path, the generated `index.html` would be served instead.

This fix addresses the issue, ensuring that the appropriate `.html` is served when using the Vite dev-server.

Closes #27044
  • Loading branch information
alan-agius4 committed Feb 7, 2024
1 parent b59f663 commit 8d5af1d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ 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) => {
describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget, isVite) => {
const javascriptFileContent =
"import {foo} from 'unresolved'; /* a comment */const foo = `bar`;\n\n\n";

Expand Down Expand Up @@ -70,5 +70,74 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
expect(result?.success).toBeTrue();
expect(await response?.status).toBe(404);
});

it('should return 404 for non existing assets', async () => {
setupTarget(harness, {
assets: ['src/extra.js'],
optimization: {
scripts: true,
},
});

harness.useTarget('serve', {
...BASE_OPTIONS,
});

const { result, response } = await executeOnceAndFetch(harness, 'extra.js');

expect(result?.success).toBeTrue();
expect(await response?.status).toBe(404);
});

it(`should return the asset that matches 'index.html' when path has a trailing '/'`, async () => {
await harness.writeFile(
'src/login/index.html',
'<html><body><h1>Login page</h1></body><html>',
);

setupTarget(harness, {
assets: ['src/login'],
optimization: {
scripts: true,
},
});

harness.useTarget('serve', {
...BASE_OPTIONS,
});

const { result, response } = await executeOnceAndFetch(harness, 'login/');

expect(result?.success).toBeTrue();
expect(await response?.status).toBe(200);
expect(await response?.text()).toContain('<h1>Login page</h1>');
});

(isVite ? it : xit)(
`should return the asset that matches '.html' when path has no trailing '/'`,
async () => {
await harness.writeFile(
'src/login/new.html',
'<html><body><h1>Login page</h1></body><html>',
);

setupTarget(harness, {
assets: ['src/login'],
optimization: {
scripts: true,
},
});

harness.useTarget('serve', {
...BASE_OPTIONS,
});

const { result, response } = await executeOnceAndFetch(harness, 'login/new');

expect(result?.success).toBeTrue();
expect(await response?.status).toBe(200);
expect(await response?.text()).toContain('<h1>Login page</h1>');
},
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,8 @@ export async function setupServer(
publicDir: false,
esbuild: false,
mode: 'development',
appType: 'mpa',
// We use custom as we do not rely on Vite's htmlFallbackMiddleware and indexHtmlMiddleware.
appType: 'custom',
css: {
devSourcemap: true,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,23 @@ export function createAngularMemoryPlugin(options: AngularMemoryPluginOptions):
return;
}

// HTML fallbacking
// This matches what happens in the vite html fallback middleware.
// ref: https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/htmlFallback.ts#L9
const htmlAssetSourcePath =
pathname[pathname.length - 1] === '/'
? // Trailing slash check for `index.html`.
assets.get(pathname + 'index.html')
: // Non-trailing slash check for fallback `.html`
assets.get(pathname + '.html');

if (htmlAssetSourcePath) {
req.url = `${server.config.base}@fs/${encodeURI(htmlAssetSourcePath)}`;
next();

return;
}

// Resource files are handled directly.
// Global stylesheets (CSS files) are currently considered resources to workaround
// dev server sourcemap issues with stylesheets.
Expand Down

0 comments on commit 8d5af1d

Please sign in to comment.