简体   繁体   English

动态目录不会部署在 Vercel 上(...但适用于 localhost)

[英]Dynamic table of contents won't deploy on Vercel (... but works on localhost)

I'm trying to add a dynamic table of contents to my blogpage in next.js.我正在尝试在 next.js 中向我的博客页面添加动态目录。 The code is running perfectly on my localhost, but as soon as I'm deploying it to vercel I got this error:该代码在我的本地主机上完美运行,但是一旦我将它部署到 vercel,我就收到了这个错误:

TypeError: Cannot read properties of undefined (reading 'content')
at BlogPost (/vercel/path0/.next/server/pages/posts/[slug].js:111:23)
at Jc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:64:191)
at Mc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:66:253)
at Z (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:71:89)
at Nc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:73:98)
at Mc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:67:131)
at Z (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:71:89)
at Mc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:70:13)
at Z (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:71:89)
at Nc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:73:98)

I found out that the build failure is produced by the command.processSync on line 85 (I wrote a comment there).我发现构建失败是由第 85 行的 command.processSync 产生的(我在那里写了一条评论)。 Sadly I'm unable to fix this... Any suggestions and help why this happens?可悲的是我无法解决这个问题......任何建议和帮助为什么会发生这种情况?

Here is the full code: ( I delete the grahpcms route when creating the GraphQLClient for safety, so that's not the failure here.)这是完整的代码:(为了安全起见,我在创建 GraphQLClient 时删除了 grahpcms 路由,所以这不是这里的失败。)

import { GraphQLClient, gql } from "graphql-request";
import { useRouter } from "next/router";
import { unified } from "unified";
import rehypeParse from "rehype-parse/lib";
import rehypeStringify from "rehype-stringify/lib";
import { visit } from "unist-util-visit";
import parameterize from "parameterize";

const graphcms = new GraphQLClient();

const QUERY = gql`
  query Post($slug: String!) {
    post(where: { slug: $slug }) {
      title
      id
      content {
        html
      }
      datePublish
      coverPhoto {
        url
      }
      datePublish
    }
  }
`;

const SLUGLIST = gql`
  {
    posts {
      slug
    }
  }
`;

export async function getStaticPaths() {
  const { posts } = await graphcms.request(SLUGLIST);
  return {
    paths: posts.map((post) => ({ params: { slug: post.slug } })),
    fallback: true,
  };
}

export async function getStaticProps({ params }) {
  const slug = params.slug;
  const data = await graphcms.request(QUERY, { slug });
  const post = data.post;
  return {
    props: {
      post,
    },
  };
}

export default function BlogPost({ post }) {
  const router = useRouter();

  var toc = [];

  //Forms the HTML String into a tree that we can add logic too
  //Then forms that tree back into html string
  const newContent = unified()
    .use(rehypeParse, {
      fragment: true,
    })
    .use(() => {
      return (tree) => {
        visit(tree, "element", (node) => {
          if (node.tagName === "h2") {
            const id = parameterize(node.children[0].value);
            node.properties.id = id;
            toc.push({
              id: node.properties.id,
              title: node.children[0].value,
            });
            console.log("id", id);
          }
        });
      };
    })
    .use(rehypeStringify)
    //THIS IS WHERE THE DELPLOYMENT FAILS
    .processSync(post.content.html)
    .toString();

  if (router.isFallback) {
    return <h2>Loading</h2>;
  }

  return (
    <div>
      <header>
        <h1>{post.title}</h1>
        <img
          src={post.coverPhoto.url}
          width="100%"
          style={{ borderRadius: "1rem" }}></img>
        <span>Published: {post.datePublish}</span>
      </header>
      <main>
        <div>
          {toc.map(({ id, title }) => {
            return (
              <li style={{ listStyle: "none" }} key={id}>
                <a style={{ fontSize: "1.1rem" }} href={`#${id}`}>
                  <b> {title}</b>
                </a>
              </li>
            );
          })}
        </div>
        <div
          className="blogpost"
          dangerouslySetInnerHTML={{ __html: newContent }}
        />
      </main>
    </div>
  );
}

Thank you very much!非常感谢!

I would try to use operator of optional changing like this:我会尝试像这样使用可选更改的运算符:

post?.content?.html

Second step is to build project on your computer not to wait for building on vercel and detect another error.第二步是在您的计算机上构建项目,而不是等待在 vercel 上构建并检测另一个错误。

PS You can handle undefined props by if statement but only don't forget to place it before main return statement and after all hooks. PS 您可以通过 if 语句处理未定义的道具,但不要忘记将其放在 main return 语句之前和所有钩子之后。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM