使用'fetch'或其他方法代替'fs'读取NextJS中的markdownfiles

olmpazwi  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(85)

我正在做一个博客包含数学公式的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

字符串
它在localhost上运行得很好。但是在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文件?还有什么替代方法可以导入markdown文件,而不会与边缘运行冲突?
先谢了。

vohkndzv

vohkndzv1#

在将使用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获取getStaticPaths提供的postID,读取相应的markdown文件,并将内容作为props传递到您的页面。
  3. BlogPage组件接收post内容作为props并呈现它。

希望这可以帮助你!!

相关问题