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

olmpazwi  于 2024-01-07  发布在  其他
关注(0)|答案(1)|浏览(89)

我正在做一个博客包含数学公式的markdown页面。我有markdown文件本地存储在一个文件夹中。这是我的博客页面。tsx-

  1. import React from 'react'
  2. import fs from "fs"
  3. import Markdown from "react-markdown"
  4. import rehypeKatex from "rehype-katex"
  5. import remarkMath from "remark-math"
  6. import rehypeRaw from "rehype-raw"
  7. import matter from "gray-matter"
  8. import 'katex/dist/katex.min.css'
  9. // export const runtime = 'edge'
  10. const getPostContent = (postID: string) => {
  11. const folder = "src/blogPosts";
  12. const file = `${folder}/${postID}.md`;
  13. const content = fs.readFileSync(file, "utf8");
  14. const matterResult = matter(content);
  15. return matterResult;
  16. };
  17. export const generateStaticParams = async () => {
  18. return [{ postID: "blog-post1" }]
  19. };
  20. const BlogPage = (props: any) => {
  21. const postID = props.params.postID;
  22. const post = getPostContent(postID)
  23. return (
  24. <>
  25. <h1>{post.data.title}</h1>
  26. <Markdown remarkPlugins={[remarkMath]} rehypePlugins={[rehypeKatex, rehypeRaw]}>
  27. {post.content}</Markdown>
  28. </>
  29. )
  30. }
  31. export default BlogPage

字符串
它在localhost上运行得很好。但是在Cloudflare页面上尝试部署时出错。

  1. 19:18:58.294 ⚡️ Completed `npx vercel build`.
  2. 19:18:58.342 ⚡️ Invalid prerender config for /allblogs/[postID]
  3. 19:18:58.343 ⚡️ Invalid prerender config for /allblogs/[postID].rsc
  4. 19:18:59.959
  5. 19:18:59.960 ⚡️ ERROR: Failed to produce a Cloudflare Pages build from the project.
  6. 19:18:59.961 ⚡️
  7. 19:18:59.961 ⚡️ The following routes were not configured to run with the Edge Runtime:
  8. 19:18:59.961 ⚡️ - /allblogs/[postID]
  9. 19:18:59.961 ⚡️
  10. 19:18:59.962 ⚡️ Please make sure that all your non-static routes export the following edge runtime route segment config:
  11. 19:18:59.962 ⚡️ export const runtime = 'edge';
  12. 19:18:59.962 ⚡️
  13. 19:18:59.962 ⚡️ You can read more about the Edge Runtime on the Next.js documentation:
  14. 19:18:59.962 ⚡️ https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes
  15. 19:18:59.962
  16. 19:18:59.992 Failed: Error while executing user command. Exited with error code: 1
  17. 19:19:00.002 Failed: build command exited with code: 1
  18. 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

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


但它抛出了一个错误-

  1. 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提供服务,而无需访问文件系统。

  1. import React from 'react';
  2. import fs from 'fs';
  3. import path from 'path';
  4. import Markdown from 'react-markdown';
  5. import rehypeKatex from 'rehype-katex';
  6. import remarkMath from 'remark-math';
  7. import rehypeRaw from 'rehype-raw';
  8. import matter from 'gray-matter';
  9. import 'katex/dist/katex.min.css';
  10. const postsDirectory = path.join(process.cwd(), 'src/blogPosts');
  11. export async function getStaticPaths() {
  12. // Read all markdown files in the postsDirectory
  13. const filenames = fs.readdirSync(postsDirectory);
  14. // Create a route for each markdown file
  15. const paths = filenames.map((filename) => {
  16. return {
  17. params: {
  18. postID: filename.replace(/\.md$/, ''),
  19. },
  20. };
  21. });
  22. return {
  23. paths,
  24. fallback: false,
  25. };
  26. }
  27. export async function getStaticProps({ params }) {
  28. // Read the markdown file for the current postID
  29. const fullPath = path.join(postsDirectory, `${params.postID}.md`);
  30. const fileContents = fs.readFileSync(fullPath, 'utf8');
  31. // Parse the post metadata section
  32. const matterResult = matter(fileContents);
  33. // Pass the post data to the page via props
  34. return {
  35. props: {
  36. post: matterResult,
  37. },
  38. };
  39. }
  40. const BlogPage = ({ post }) => {
  41. return (
  42. <>
  43. <h1>{post.data.title}</h1>
  44. <Markdown
  45. remarkPlugins={[remarkMath]}
  46. rehypePlugins={[rehypeKatex, rehypeRaw]}
  47. >
  48. {post.content}
  49. </Markdown>
  50. </>
  51. );
  52. };
  53. export default BlogPage;

字符串
让我解释一下上面的代码:

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

希望这可以帮助你!!

展开查看全部

相关问题