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

[Bug]: Blog Quickstart Netlify: ENOENT: no such file or directory, scandir '/Users/Dev/remix-quick-start-blog/netlify/functions/server/posts' #448

Closed
12 tasks
M0nica opened this issue Nov 22, 2021 · 11 comments
Labels
bug Something isn't working

Comments

@M0nica
Copy link
Contributor

M0nica commented Nov 22, 2021

Which Remix packages are impacted?

  • remix (Remix core)
  • create-remix
  • @remix-run/architect
  • @remix-run/cloudflare-workers
  • @remix-run/dev
  • @remix-run/express
  • @remix-run/netlify
  • @remix-run/node
  • @remix-run/react
  • @remix-run/serve
  • @remix-run/server-runtime
  • @remix-run/vercel

What version of Remix are you using?

^1.0.3

Steps to Reproduce

Follow the quick start blog guide (and configure site with Netlify) up to this step https://remix.run/docs/en/dev/tutorials/blog#pulling-from-a-data-source that requires let postsPath = path.join(__dirname, "../posts"); to be added to get the posts.

Navigate to localhost:3000/posts and see the error message ENOENT: no such file or directory, scandir 'remix-quick-start-blog/netlify/functions/server/posts'.

Expected Behavior

Following the tutorial's instructions of:

💿 Create a "posts/" folder in the root of the project, not in the app directory, but next to it.

mkdir posts
Now add some posts:

touch posts/my-first-post.md
touch posts/90s-mixtape.md

will result in navigating to http://localhost:3000/posts displaying a list of the posts

Actual Behavior

Following the tutorial's instructions of:

💿 Create a "posts/" folder in the root of the project, not in the app directory, but next to it.

mkdir posts
Now add some posts:

touch posts/my-first-post.md
touch posts/90s-mixtape.md

will result in navigating to http://localhost:3000/posts displays an error message ENOENT: no such file or directory, scandir 'remix-quick-start-blog/netlify/functions/server/posts'. unless the posts folder is moved into the netlify/functions/server folder.

Additional Information

Moving the posts folder into netlify/functions/server resolved the issue for me but the tutorials says to put the posts in the root directory. Is the expected functionality that users should put the posts in the netlify/functions/ folder in order for the project to work as expected? If so, can the tutorial documents be updated? If not, is additional configuration required for Netlify? I opened a PR related to Netlify needing additional setup for the quick start tutorial #446

I see the Jokes App tutorial mentions:

Remix can be deployed in a large and growing list of JavaScript environments. The "Remix App Server" is a full-featured Node.js server based on Express. It's the simplest option and it satisfies most people's needs, so that's what we're going with for this tutorial. Feel free to experiment in the future!

Instead of adding instructions for specific deployment targets (the current proposed changes) should a similar disclaimer be added to https://remix.run/docs/en/dev/tutorials/blog instead? to make it clear that the tutorial is assuming the deployment target is Remix App Server? The instructions made it seem like it's choose your own adventure in terms of which deployment target you choose during the set up process.

@chuygil
Copy link

chuygil commented Nov 27, 2021

Ran into this same issue today.

@martylouis
Copy link

from @ryanflorence comment on #564

The tutorial makes it more clear you should use the remix app server now, the file system stuff is relative to the output directory, not the source, go back one more directory since you're actually in "server/posts/{server-output-file}.js"

This worked for me:

// post.ts

const postsPath = path.join(__dirname, '../..', 'posts');

@ningo-agilityio
Copy link

Hi @ryanflorence I got the same issue, I even added the path

const postsPath = path.join(__dirname, "../..", "posts-data");

But it is still fail on Vercel

ENOENT: no such file or directory, scandir '/var/task/output/server/pages/posts-data'

Do I miss anything?

@conorkelly86
Copy link

I have the same issue as @ningo-agilityio but I am using Netlify

@nsantos16
Copy link

Same issue here! __dirname is api/_build

@mohammedmulazada
Copy link

mohammedmulazada commented Dec 19, 2021

Same here! :( On Vercel.

@yhuard
Copy link

yhuard commented Dec 19, 2021

Hi! On my side, I managed to make it work. Here's what I did:

First, I updated the path in app/post.ts:

// Relative to the server output not the source!
// i.e. netlify/functions/server/build/index.js
const postsPath = path.join(__dirname, "../../../..", "posts");

Then, netlify returned errors when navigating to the deployed post, because it couldn't locate the posts folder. So I updated netlify.toml to add:

[functions]
  included_files = ["posts/**"]

Now, the demo is working fine.

Also, please note that for whatever reason, netlify doesn't support import fs from "fs/promises";. Use import { promises as fs } from "fs"; instead.

@vldmrkl
Copy link

vldmrkl commented Dec 31, 2021

@yhuard I had this problem too:

Also, please note that for whatever reason, netlify doesn't support import fs from "fs/promises";. Use import { promises as fs } from "fs"; instead.

It's a known issue in netlify's zip-it-and-ship-it package (although they claimed to resolve the issue, some people are still experiencing it). A workaround that worked for me was changing the node_bundler in the netlify configuration, i.e.:

[functions]
  node_bundler = "esbuild"
  included_files = ["files_to_include/**"]

I believe that the path to posts will need to be
const postsPath = path.join(__dirname, "../../..", "posts"); as it will be served from .netlify/functions-serve/server/src/posts.

@Adbib
Copy link

Adbib commented Jan 20, 2022

make your Posts function like this I solve this problem

export async function getPosts() {
  const postOrSeriesBasenames = await fs.readdir(
    `${__dirname}/../../app/posts`,
    { withFileTypes: true }
  );

  const posts = await Promise.all(
    postOrSeriesBasenames
      .map(async (dirent) => {
        const file = await fs.readFile(
          path.join(`${__dirname}/../../app/posts`, dirent.name)
        );
        const { attributes } = parseFrontMatter(file.toString());
        return {
          slug: dirent.name.replace(/\.mdx/, ""),
          title: attributes.title,
        };
      })
  );

  return posts;
}

@OmerHerera
Copy link

I just got the same issue locally today, my solution its was that the path was wrong I fixed
from:

  • const postsPath = path.join(__dirname, "..", "posts");
    to
  • const postsPath = path.join(__dirname, "../..", "posts");

@ryanflorence
Copy link
Member

ryanflorence commented Feb 19, 2022

I suppose we need to be more clear that this tutorial is an introduction to the moving parts of Remix, not a literal blog tutorial. You can’t use a file system in serveless environments, as stated in the tutorial, you should use a real db.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests