Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File cannot be read in prod #5163

Closed
ScriptRaccoon opened this issue Jun 5, 2022 · 6 comments
Closed

File cannot be read in prod #5163

ScriptRaccoon opened this issue Jun 5, 2022 · 6 comments

Comments

@ScriptRaccoon
Copy link

Describe the bug

In the get function of a SvelteKit page endpoint I would like to read a file (with fs.readFileSync) which is inside the src folder and send the result to the client. This works fine in my local dev environment. But when I deploy the app to Netlify (for example) the following error shows up:

500

ENOENT: no such file or directory, open 'src/files/test.txt'

Error: ENOENT: no such file or directory, open 'src/files/test.txt

I have tried to

  1. move the file elsewhere (for example in the static folder)
  2. set the newest node version on Netlify (with the NODE_VERSION var)
  3. create an alias for the path

Maybe this is easy to solve by changing the path of the file (how?), but I really wonder why this works in dev, but not in prod.

Reproduction

  1. Create a SvelteKit skeleton project with npm init svelte. No typescript, no prettier, no ESLint, no playwright.
  2. Create src/files/test.txt with some sample text.
  3. Change index.svelte:
<script>
    export let text;
</script>

{text}
  1. Add index.js:
import fs from "fs";

export async function get() {
    const text = fs.readFileSync("src/files/test.txt", "utf8");
    return {
        body: { text },
    };
}
  1. Run npm run dev and open the app, it shows the sample text from the file.
  2. Install the Netlify adapter as described here.
  3. Deploy the site on Netlify.
  4. Open the deployed site. It throws the error shown above (it cannot find the file).

Logs

No response

System Info

System:
    OS: Windows 10 10.0.19044
    CPU: (4) x64 Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
    Memory: 1.63 GB / 7.87 GB
  Binaries:
    Node: 18.2.0 - C:\Program Files\nodejs\node.EXE
    npm: 8.11.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (102.0.1245.33)
    Internet Explorer: 11.0.19041.1566

Severity

serious, but I can work around it

Additional Information

No response

@bluwy
Copy link
Member

bluwy commented Jun 5, 2022

Reading from the filesystem is not encouraged as the build output won't match the desired path as you do in dev. It works in dev because files are left as-is (unbundled) through the dev server. Ideally you should import them, or save it in a database, etc. Marking as duplicate of #3535

@bluwy bluwy closed this as not planned Won't fix, can't repro, duplicate, stale Jun 5, 2022
@ScriptRaccoon
Copy link
Author

ScriptRaccoon commented Jun 5, 2022

Thanks! This clarifies the issue a bit. One question: what do you mean exactly by importing the files?

Also, why does the fs.readFileSync work in this project? Here markdown files are read from the file system and then rendered as html pages. For some reason there it works. Also in this project. But what should be the workaround here?

A big workaround is using mdsvex to preprocess the markdown files. This is explained in great detail here. But there must be a way to read markdown (or just plain text) files directly in SvelteKit, right?

@ScriptRaccoon
Copy link
Author

ScriptRaccoon commented Jun 5, 2022

I think I have found a solution which works at least for Netlify and my toy example. It's similar to the solution at this stackoverflow question.

  1. Create a folder for the files in the root, say files.
  2. Put the files inside (for example, test.txt).
  3. Now, we can read the file with fs.readFileSync("./files/test.txt").
  4. We have to let Netlify know about the files folder. The whole server-side code of SvelteKit gets deployed as a Netlify function. Thus, in netlify.toml we add the following:
[functions]
  included_files = ["files/**"]

It works :)

@caleb531
Copy link

caleb531 commented Jan 4, 2023

I am running into this same issue trying to call fs.readFileSync on Markdown files in my project.

@ScriptRaccoon do you know if there is a similar mechanism to include additional files/directories for Vercel deployments? When I log the directory contents on the Vercel deployment (i.e. fs.readdirSync('.'), it seems only the following files/directories are copied over from my source project.

.svelte-kit
___vc
node_modules
package.json

Right now, I'm having to resort to force-enabling SSG on my entire site (with @sveltejs/adapter-static), but it would be nice to leverage server-side capabilities.

@ScriptRaccoon
Copy link
Author

Sorry, I have no experience with Vercel.

@caleb531
Copy link

caleb531 commented Jan 4, 2023

@ScriptRaccoon No worries! I ended up discovering that leverage VIte's import.meta.glob capability to achieve the best of both worlds, so I'm back to using adapter-auto now. Credit goes to a comment from the Stack Overflow post linked above.

Granted, using import.meta.glob is still effectively pre-bundling my Markdown files, but it restores to me the ability to have fully-server-rendered pages (since I'm able to use adapter-auto again).

Maybe in the future, SvelteKit will be able to expose the filesystem path to the compiled static assets directory. Because that would allow the file-reading to be real-time, rather than performed as a build step.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants