This commit is contained in:
Bastian Wagner
2026-07-20 17:34:22 +02:00
parent aa7758c9dd
commit 45b630361d
3 changed files with 27 additions and 3 deletions

View File

@@ -1,4 +1,3 @@
import { join } from 'node:path';
import cookieParser from 'cookie-parser'; import cookieParser from 'cookie-parser';
import type { NextFunction, Request, Response } from 'express'; import type { NextFunction, Request, Response } from 'express';
import helmet from 'helmet'; import helmet from 'helmet';
@@ -11,6 +10,7 @@ import { AppModule } from './app.module';
import { createValidationPipe } from './common/security/validation.pipe'; import { createValidationPipe } from './common/security/validation.pipe';
import { AppConfigService } from './config/config.service'; import { AppConfigService } from './config/config.service';
import { MigrationHealthService } from './database/migration-health.service'; import { MigrationHealthService } from './database/migration-health.service';
import { resolvePublicAssetPath } from './static-assets';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule, { const app = await NestFactory.create<NestExpressApplication>(AppModule, {
@@ -87,7 +87,7 @@ async function bootstrap() {
}); });
} }
app.useStaticAssets(join(__dirname, '..', 'public'), { app.useStaticAssets(resolvePublicAssetPath(__dirname), {
index: false, index: false,
fallthrough: true, fallthrough: true,
}); });
@@ -96,7 +96,7 @@ async function bootstrap() {
next(); next();
return; return;
} }
res.sendFile(join(__dirname, '..', 'public', 'index.html')); res.sendFile(resolvePublicAssetPath(__dirname, 'index.html'));
}); });
await app.get(MigrationHealthService).assertNoPendingMigrations(); await app.get(MigrationHealthService).assertNoPendingMigrations();

View File

@@ -0,0 +1,16 @@
import { join } from 'node:path';
import { describe, expect, it } from 'vitest';
import { resolvePublicAssetPath } from './static-assets';
describe('resolvePublicAssetPath', () => {
it('resolves frontend files next to the compiled backend entrypoint', () => {
const runtimeDirectory = join('app', 'apps', 'backend', 'dist');
expect(resolvePublicAssetPath(runtimeDirectory)).toBe(
join(runtimeDirectory, 'public'),
);
expect(resolvePublicAssetPath(runtimeDirectory, 'index.html')).toBe(
join(runtimeDirectory, 'public', 'index.html'),
);
});
});

View File

@@ -0,0 +1,8 @@
import { join } from 'node:path';
export function resolvePublicAssetPath(
runtimeDirectory: string,
...segments: string[]
): string {
return join(runtimeDirectory, 'public', ...segments);
}