下一个应用可以在本地主机上访问文件,但在生产环境中无法访问。

huangapple go评论126阅读模式
英文:

Next App can reach a file while in localhost but not in production

问题

以下是翻译好的内容:

我正在尝试构建一个页面,该页面可以读取src/bounties/content/bounties文件夹中的一些内容mdx文件,并且我的应用程序可以在本地主机上正常工作。但是,每次我上传并在Vercel或Netlify中托管它时,都会出现ENOET错误。

这是page.tsx文件,其中调用了目录并使用next-mdx-remote呈现了mdx文件:

import { type MDXRemoteSerializeResult } from "next-mdx-remote";
import { serialize } from "next-mdx-remote/serialize";
import { promises as fs } from "fs";
import { MdxContent } from "../../mdx-content";
import BountiesBreadcrumb from "@/app/components/bountiesBreadcrumb";
import path from "path";

type Frontmatter = {
  title: string;
  date: string;
};

type Post<TFrontmatter> = {
  serialized: MDXRemoteSerializeResult;
  frontmatter: TFrontmatter;
};

interface IBountyProps {
  params: {
    slug: string;
  };
}

async function getPost(filepath: string): Promise<Post<Frontmatter>> {
  const raw = await fs.readFile(filepath, "utf-8");

  const serialized = await serialize(raw, {
    parseFrontmatter: true,
  });

  const frontmatter = serialized.frontmatter as Frontmatter;

  return {
    frontmatter,
    serialized,
  };
}

export default async function Bounty({ params }: IBountyProps) {
  const filePath = path.join(
    "src",
    "app",
    "bounties",
    "content",
    "bounties",
    `${params.slug}.mdx`
  );

  const { serialized, frontmatter } = await getPost(filePath);

  return (
    <div className="text-zinc-400 p-16 border-r border-zinc-800">
      <BountiesBreadcrumb />

      <div className="py-16 max-w-4xl">
        <h1 className="text-zinc-300 font-bold text-4xl">
          {frontmatter.title}
        </h1>

        <span className="text-zinc-400 text-md mt-8">
          Published at {frontmatter.date}
        </span>

        <div className="mt-8">
          <MdxContent source={serialized} />
        </div>
      </div>
    </div>
  );
}

例如,当用户访问路由/bounties/dynamic-sidebar时,此页面需要读取文件:src/app/bounties/content/bounties/dynamic-sidebar.mdx,然后将其呈现到页面布局中。

这是错误消息:

[Error: ENOENT: no such file or directory, open 'src/app/bounties/content/bounties/dynamic-sidebar.mdx'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'src/app/bounties/content/bounties/dynamic-sidebar.mdx'
}
[Error: ENOENT: no such file or directory, open 'src/app/bounties/content/bounties/dynamic-sidebar.mdx'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'src/app/bounties/content/bounties/dynamic-sidebar.mdx'
}
[Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.] {
  digest: '3395753351'
}
英文:

I am trying to build a page that reads some content mdx files inside the src/bounties/content/bounties folder, and my app can make it work while in localhost.
But, everytime I upload and host it in Vercel or in Netlify, it gives me the ENOET error.

This is the page.tsx file, where the directory is called and the mdx file is rendered with next-mdx-remote

import { type MDXRemoteSerializeResult } from "next-mdx-remote";
import { serialize } from "next-mdx-remote/serialize";
import { promises as fs } from "fs";
import { MdxContent } from "../../mdx-content";
import BountiesBreadcrumb from "@/app/components/bountiesBreadcrumb";
import path from "path";

type Frontmatter = {
  title: string;
  date: string;
};

type Post<TFrontmatter> = {
  serialized: MDXRemoteSerializeResult;
  frontmatter: TFrontmatter;
};

interface IBountyProps {
  params: {
    slug: string;
  };
}

async function getPost(filepath: string): Promise<Post<Frontmatter>> {
  const raw = await fs.readFile(filepath, "utf-8");

  const serialized = await serialize(raw, {
    parseFrontmatter: true,
  });

  const frontmatter = serialized.frontmatter as Frontmatter;

  return {
    frontmatter,
    serialized,
  };
}

export default async function Bounty({ params }: IBountyProps) {
  const filePath = path.join(
    "src",
    "app",
    "bounties",
    "content",
    "bounties",
    `${params.slug}.mdx`
  );

  const { serialized, frontmatter } = await getPost(filePath);

  return (
    <div className="text-zinc-400 p-16 border-r border-zinc-800">
      <BountiesBreadcrumb />

      <div className="py-16 max-w-4xl">
        <h1 className="text-zinc-300 font-bold text-4xl">
          {frontmatter.title}
        </h1>

        <span className="text-zinc-400 text-md mt-8">
          Published at {frontmatter.date}
        </span>

        <div className="mt-8">
          <MdxContent source={serialized} />
        </div>
      </div>
    </div>
  );
}

For example, when the user reaches the route /bounties/dynamic-sidebar, this page needs to read the file: src/app/bounties/content/bounties/dynamic-sidebar.mdx and then render it into the page layout.

There's the error message:

[Error: ENOENT: no such file or directory, open 'src/app/bounties/content/bounties/dynamic-sidebar.mdx'] {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: 'src/app/bounties/content/bounties/dynamic-sidebar.mdx'
}
[Error: ENOENT: no such file or directory, open 'src/app/bounties/content/bounties/dynamic-sidebar.mdx'] {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: 'src/app/bounties/content/bounties/dynamic-sidebar.mdx'
}
[Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.] {
digest: '3395753351'
}

答案1

得分: 1

The problem you are facing probably has to do with the way you are generating the file path to search for. Try the following example instead, this should work:

const workDirPath = process.cwd(); 
const contentPath = "src/app/bounties/content/bounties";
const filePath = path.join(workDirPath, contentPath, `${params.slug}.mdx`);

As you see I use the process.cwd function in the above example, this ensures that you are pointing to your project root and only then joining your relative path to it.

英文:

The problem you are facing probably has to do with the way you are generating the file path to search for. Try the following example instead, this should work:

const workDirPath = process.cwd(); 
const contentPath = "src/app/bounties/content/bounties";
const filePath = path.join(workDirPath, contentPath, `${params.slug}.mdx`);

As you see I use the process.cwd function in the above example, this ensures that you are pointing to your project root and only then joining your relative path to it.

huangapple
  • 本文由 发表于 2023年6月30日 04:31:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76584435.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定