'SvelteKit + Vercel Broken path

Im having a problem using readdirSync when using SvelteKit + vercel. The site deploys successfully but one of the serverside load functions fails on a path

The problem does not occur locally if i use npm run dev and it doesnt appear with a local production build via npm run build && npm run preview. The problem appears to be with the path that readdirsync() looks for. But im unable to figure out how to fix this

[index].json.js

import fs from 'fs';
import dayjs from 'dayjs';

export function get() {
    let posts = fs
        .readdirSync(`src/posts`) // <-- this path breaks when deployed with vercel
        .filter((fileName) => /.+\.md$/.test(fileName))
        .map((fileName) => {
            const { metadata, content } = process(`src/posts/${fileName}`);
            return {
                content,
                metadata,
                slug: fileName.slice(0, -3)
            };
        });
    // sort the posts by create date.
    posts.sort(
        (a, b) => dayjs(a.metadata.date, 'MMM D, YYYY') - dayjs(b.metadata.date, 'MMM D, YYYY')
    );
    let body = JSON.stringify(posts);

    return {
        body
    };
}

This is the logs i see in Vercel. Its obvious the path is broken possibly due to incorrect base path, but how do i fix it?

[HEAD] /
11:50:50:04
2021-12-20T16:50:50.092Z    d7448652-906d-49d1-b9f0-938984ab2d18    ERROR   Error: ENOENT: no such file or directory, scandir 'src/posts'
    at Object.readdirSync (fs.js:1047:3)
    at get (/var/task/index.js:56304:33)
    at render_endpoint (/var/task/index.js:56582:26)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async resolve (/var/task/index.js:57661:56)
    at async Object.handle (/var/task/index.js:57999:24)
    at async respond (/var/task/index.js:57644:12)
    at async fetch (/var/task/index.js:57182:28)
    at async load2 (/var/task/index.js:56440:17)
    at async load_node (/var/task/index.js:57265:14)
2021-12-20T16:50:50.093Z    d7448652-906d-49d1-b9f0-938984ab2d18    ERROR   SyntaxError: Unexpected token E in JSON at position 0
    at JSON.parse (<anonymous>)
    at Proxy.<anonymous> (/var/task/index.js:57247:31)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async load2 (/var/task/index.js:56440:17)
    at async load_node (/var/task/index.js:57265:14)
    at async respond$1 (/var/task/index.js:57387:22)
    at async render_page (/var/task/index.js:57516:20)
    at async resolve (/var/task/index.js:57661:104)
    at async Object.handle (/var/task/index.js:57999:24)
    at async respond (/var/task/index.js:57644:12)


Solution 1:[1]

In the end, I opted not to use readdirSync for this case. I'm not entirely sure why it didn't work but since I'm using Vite anyway (from SvelteKit), I chose to try using import.meta.glob and it worked as desired. The API is slightly different though. Working code:

import { slugFromPath } from '$lib/util';

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function get({ query }) {
    const modules = import.meta.glob('./*.{md,svx,svelte.md}');

    const postPromises = [];
    const limit = Number(query.get('limit') ?? Infinity);

    if (Number.isNaN(limit)) {
        return {
            status: 400
        };
    }

    for (let [path, resolver] of Object.entries(modules)) {
        const slug = slugFromPath(path);
        const promise = resolver().then((post) => ({
            slug,
            ...post.metadata
        }));

        postPromises.push(promise);
    }

    const posts = await Promise.all(postPromises);
    const publishedPosts = posts.filter((post) => post.published).slice(0, limit);

    publishedPosts.sort((a, b) => (new Date(a.date) > new Date(b.date) ? -1 : 1));

    return {
        body: publishedPosts.slice(0, limit)
    };

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Paolo