在NextJS中使用'fetch'或其他方法代替'fs'读取markdown文件

问题描述 投票:0回答:1

我正在制作一个博客,其中包含 Markdown 页面上的数学公式。我将 Markdown 文件存储在本地文件夹中。这是我的博客页面.tsx-


import React from 'react'

import fs from "fs"

import Markdown from "react-markdown"
import rehypeKatex from "rehype-katex"
import remarkMath from "remark-math"
import rehypeRaw from "rehype-raw"
import matter from "gray-matter"
import 'katex/dist/katex.min.css'


// export const runtime = 'edge'
const getPostContent = (postID: string) => {

  const folder = "src/blogPosts";
  const file = `${folder}/${postID}.md`;
  const content = fs.readFileSync(file, "utf8");
  const matterResult = matter(content);
  return matterResult;
};

export const generateStaticParams = async () => {

  return [{ postID: "blog-post1" }]
};



const BlogPage = (props: any) => {



  const postID = props.params.postID;
  const post = getPostContent(postID)



  return (

    <>
      <h1>{post.data.title}</h1>

      <Markdown remarkPlugins={[remarkMath]} rehypePlugins={[rehypeKatex, rehypeRaw]}>
        {post.content}</Markdown>

    </>

  )
}

export default BlogPage



它在本地主机上完美运行。但尝试在 Cloudflare 页面上部署时出现错误。


19:18:58.294    ⚡️ Completed `npx vercel build`.
19:18:58.342    ⚡️ Invalid prerender config for /allblogs/[postID]
19:18:58.343    ⚡️ Invalid prerender config for /allblogs/[postID].rsc
19:18:59.959    
19:18:59.960    ⚡️ ERROR: Failed to produce a Cloudflare Pages build from the project.
19:18:59.961    ⚡️ 
19:18:59.961    ⚡️  The following routes were not configured to run with the Edge Runtime:
19:18:59.961    ⚡️    - /allblogs/[postID]
19:18:59.961    ⚡️ 
19:18:59.962    ⚡️  Please make sure that all your non-static routes export the following edge runtime route segment config:
19:18:59.962    ⚡️    export const runtime = 'edge';
19:18:59.962    ⚡️ 
19:18:59.962    ⚡️  You can read more about the Edge Runtime on the Next.js documentation:
19:18:59.962    ⚡️    https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes
19:18:59.962    
19:18:59.992    Failed: Error while executing user command. Exited with error code: 1
19:19:00.002    Failed: build command exited with code: 1
19:19:01.023    Failed: error occurred while running build command

在页面上添加

export const runtime = 'edge'
与'fs'模块冲突并显示错误-

Error: Module not found: Can't resolve 'fs'

边缘运行时似乎与nodejs模块冲突。作为“fs”的替代品,我尝试使用像这样的

fetch


const getPostContent = async (postID: string) => {
  const resource = await import(`${folder}/${postID}.md`);
  const res = await fetch(resource.default);
  console.log(res)
  if (!res.ok) {
      throw new Error(`${resource.default}: ${res.status} ${res.statusText}`);
  }
  return res.text();
  };

但是它抛出了一个错误-

⨯ unhandledRejection: Error: Cannot find module 

此时我陷入困境。谁能帮我阅读 markdown 文件吗? 还有其他方法可以导入不会与 Edge Runtume 冲突的 Markdown 文件吗?

提前致谢。

typescript next.js fetch-api node.js-fs cloudflare-pages
1个回答
0
投票

在将使用 Node.js 特定模块(如 fs)的 Next.js 应用程序部署到 Cloudflare Pages 等静态托管提供商时,您似乎遇到了一个常见问题。

fs 模块在浏览器或 Cloudflare Pages 用于动态路由的无服务器函数中不可用。

要解决您的问题,您应该使用 Next.js 的 getStaticProps 和 getStaticPaths 函数在构建时而不是在运行时读取 markdown 文件。

这样,您可以将每篇博客文章预渲染为静态页面,该页面可以直接由 Cloudflare Pages 提供,无需访问文件系统。

import React from 'react';
import fs from 'fs';
import path from 'path';
import Markdown from 'react-markdown';
import rehypeKatex from 'rehype-katex';
import remarkMath from 'remark-math';
import rehypeRaw from 'rehype-raw';
import matter from 'gray-matter';
import 'katex/dist/katex.min.css';

const postsDirectory = path.join(process.cwd(), 'src/blogPosts');

export async function getStaticPaths() {
  // Read all markdown files in the postsDirectory
  const filenames = fs.readdirSync(postsDirectory);

  // Create a route for each markdown file
  const paths = filenames.map((filename) => {
    return {
      params: {
        postID: filename.replace(/\.md$/, ''),
      },
    };
  });

  return {
    paths,
    fallback: false,
  };
}

export async function getStaticProps({ params }) {
  // Read the markdown file for the current postID
  const fullPath = path.join(postsDirectory, `${params.postID}.md`);
  const fileContents = fs.readFileSync(fullPath, 'utf8');

  // Parse the post metadata section
  const matterResult = matter(fileContents);

  // Pass the post data to the page via props
  return {
    props: {
      post: matterResult,
    },
  };
}

const BlogPage = ({ post }) => {
  return (
    <>
      <h1>{post.data.title}</h1>
      <Markdown
        remarkPlugins={[remarkMath]}
        rehypePlugins={[rehypeKatex, rehypeRaw]}
      >
        {post.content}
      </Markdown>
    </>
  );
};

export default BlogPage;

我来解释一下上面的代码:

  1. getStaticPaths
    读取
    src/blogPosts
    目录中的所有 Markdown 文件并为其生成路径。 这告诉 Next.js 在构建时生成哪些页面。
  2. getStaticProps
    获取
    postID
    提供的
    getStaticPaths
    ,读取相应的 markdown 文件,并将内容作为 props 传递到您的页面。
  3. BlogPage
    组件接收帖子内容作为道具并渲染它。

希望可以帮到你!!!

© www.soinside.com 2019 - 2024. All rights reserved.