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

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions