Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): serve assets from the provided `s…
Browse files Browse the repository at this point in the history
…erve-path`

When the `serve-path` option is used assets are now correctly servered from this location.

Closes angular#26509
  • Loading branch information
alan-agius4 committed Nov 28, 2023
1 parent 43f22f4 commit 4128634
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ describeServeBuilder(
(harness, setupTarget, isViteRun) => {
describe('option: "servePath"', () => {
beforeEach(async () => {
setupTarget(harness);
setupTarget(harness, {
assets: ['src/assets'],
});

// Application code is not needed for these tests
await harness.writeFile('src/main.ts', 'console.log("foo");');
Expand Down Expand Up @@ -96,6 +98,23 @@ describeServeBuilder(
expect(result?.success).toBeTrue();
expect(await response?.text()).toContain('<title>');
});

it('serves assets at specified path when option is used', async () => {
await harness.writeFile('src/assets/test.txt', 'hello world!');

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

const { result, response } = await executeOnceAndFetch(harness, '/test/assets/test.txt', {
// fallback processing requires an accept header
request: { headers: { accept: 'text/html' } },
});

expect(result?.success).toBeTrue();
expect(await response?.text()).toContain('hello world');
});
});
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -583,15 +583,16 @@ export async function setupServer(

// Parse the incoming request.
// The base of the URL is unused but required to parse the URL.
const pathname = pathnameWithoutServePath(req.url, serverOptions);
const pathname = pathnameWithoutBasePath(req.url, server.config.base);
const extension = extname(pathname);

// Rewrite all build assets to a vite raw fs URL
const assetSourcePath = assets.get(pathname);
console.warn({ s: server.config.base });
if (assetSourcePath !== undefined) {
// The encoding needs to match what happens in the vite static middleware.
// ref: https://github.com/vitejs/vite/blob/d4f13bd81468961c8c926438e815ab6b1c82735e/packages/vite/src/node/server/middlewares/static.ts#L163
req.url = `/@fs/${encodeURI(assetSourcePath)}`;
req.url = `${server.config.base}@fs/${encodeURI(assetSourcePath)}`;
next();

return;
Expand Down Expand Up @@ -689,7 +690,7 @@ export async function setupServer(

// Parse the incoming request.
// The base of the URL is unused but required to parse the URL.
const pathname = pathnameWithoutServePath(req.url, serverOptions);
const pathname = pathnameWithoutBasePath(req.url, server.config.base);

if (pathname === '/' || pathname === `/index.html`) {
const rawHtml = outputFiles.get('/index.html')?.contents;
Expand Down Expand Up @@ -801,17 +802,12 @@ async function loadViteClientCode(file: string) {
return contents;
}

function pathnameWithoutServePath(url: string, serverOptions: NormalizedDevServerOptions): string {
function pathnameWithoutBasePath(url: string, basePath: string): string {
const parsedUrl = new URL(url, 'http://localhost');
let pathname = decodeURIComponent(parsedUrl.pathname);
if (serverOptions.servePath && pathname.startsWith(serverOptions.servePath)) {
pathname = pathname.slice(serverOptions.servePath.length);
if (pathname[0] !== '/') {
pathname = '/' + pathname;
}
}
const pathname = decodeURIComponent(parsedUrl.pathname);

return pathname;
// slice(basePath.length - 1) to retain the trailing slash
return basePath && pathname.startsWith(basePath) ? pathname.slice(basePath.length - 1) : pathname;
}

type ViteEsBuildPlugin = NonNullable<
Expand Down

0 comments on commit 4128634

Please sign in to comment.