'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 |
