Skip to content

Path setting is broken if elysia is started from a location that is not the directory of the package in which elysia runs (e.g. monorepo) #48

@kakkokari-gtyih

Description

@kakkokari-gtyih

I have a project with the following directory structure:

my_app/
├─ packages/
│  ├─ backend/
│  │  ├─ index.ts
│  │  ├─ package.json
│  ├─ frontend/
│  │  ├─ ....ts
│  │  ├─ package.json
├─ frontend_dist/
├─ package.json

It's a monorepo configuration, where the backend contains the Elysia server where @elysiajs/static is used and the frontend contains the frontend code (vite).
The frontend artifacts are stored in frontend_dist folder in the root directory when built and is referenced by Elysia with the following code:

import { promises as fsp } from 'node:fs';
import { Elysia } from 'elysia';
import { staticPlugin } from '@elysiajs/static';
import { html, Html } from '@elysiajs/html';

async function getManifest() {
    if (process.env.NODE_ENV === 'development') {
        return null;
    }

    const manifestPath = '../../frontend_dist/manifest.json';
    if (await fsp.exists(manifestPath)) {
        return JSON.parse(await fsp.readFile(manifestPath, 'utf-8'))['src/main.ts'];
    } else {
        return null;
    }
}

function serveVite() {
    if (process.env.NODE_ENV === 'development') {
        return new Elysia().get('/vite/*', async ({ request }) => {
            const url = new URL(request.url);
            url.port = '5174';
            const modifiedRequest = new Request(url.toString(), request);
            return await fetch(modifiedRequest);
        });
    } else {
        return new Elysia().use(staticPlugin({
            assets: '../../frontend_dist',
            prefix: '/vite',
        }));
    }
}

export const webServer = new Elysia()
    .use(html())
    .use(serveVite())
    .get('/*', async ({ params, error }) => {
        if (params['*'].startsWith('vite')) {
            return error(404, {
                message: 'Not Found',
                status: 404,
            });
        }

        const manifest = await getManifest();
        
        return (
            <html>
                <head>
                    <title>My App</title>
                    {!manifest && <script type="module" src="/vite/@vite/client"></script>}
                    {manifest ? (
                        <>
                            {Array.isArray(manifest.css) && manifest.css.map((css: string) => (
                                <link rel="stylesheet" href={`/vite/${css}`} />
                            ))}
                            <script type="module" src={`/vite/${manifest.file}`}></script>
                        </>
                    ) : (
                        <>
                            <script type="module" src="/vite/@vite/client"></script>
                            <script type="module" src="/vite/src/main.ts"></script>
                        </>
                    )}
                </head>
                <body>
                    <div id="app"></div>
                </body>
            </html>
        );
    })

And if I start this from the root directory of monorepo with the following command, the file is not served.

bun --filter backend start

Strangely, after navigating to packages/backend and then starting the server, it works as expected.

cd packages/backend
bun run start

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions