ECONNREFUSED 在“下一个构建”期间。与“下一个开发者”配​​合良好

use*_*200 6 build mongodb hadoop-yarn next.js

我有一个非常简单的 NextJS 9.3.5 项目。目前,它有一个页面/用户和一个pages/api/users从本地 MongoDB 表中检索所有用户的页面

它使用“next dev”在本地构建良好但是,它在“next build”失败并出现ECONNREFUSED错误

页面/用户

import fetch from "node-fetch"
import Link from "next/link"

export async function getStaticProps({ params }) {
  const res = await fetch(`http://${process.env.VERCEL_URL}/api/users`)
  const users = await res.json()
  return { props: { users } }
}

export default function Users({ users }) {
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>
          <Link href="/user/[id]" as={`/user/${user._id}`}>
            <a>{user.name}</a>
          </Link>
        </li>
      ))}
    </ul>
  );
}
Run Code Online (Sandbox Code Playgroud)

页面/api/用户

import mongoMiddleware from "../../lib/api/mongo-middleware";
import apiHandler from "../../lib/api/api-handler";

export default mongoMiddleware(async (req, res, connection, models) => {
  const {
    method
  } = req

  apiHandler(res, method, {
    GET: (response) => {
      models.User.find({}, (error, users) => {
        if (error) {
          connection.close();
          response.status(500).json({ error });
        } else {
          connection.close();
          response.status(200).json(users);
        }
      })
    }
  });
})
Run Code Online (Sandbox Code Playgroud)

纱线构建

yarn run v1.22.4
$ next build
Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`
> Info: Loaded env from .env
Creating an optimized production build

Compiled successfully.

> Info: Loaded env from .env
Automatically optimizing pages ..
Error occurred prerendering page "/users". Read more: https://err.sh/next.js/prerender-error:
FetchError: request to http://localhost:3000/api/users failed, reason: connect ECONNREFUSED 127.0.0.1:3000
Run Code Online (Sandbox Code Playgroud)

任何想法出了什么问题?特别是当它与“下一个开发者”一起工作时?

谢谢你。

Ric*_*las 12

几天前我尝试过同样的方法但没有用...因为当我们构建应用程序时,我们没有可用的本地主机...检查文档的这一部分 - https://nextjs.org/docs/basic -features/data-fetching#write-server-side-code-directly - 说:“你不应该从 getStaticProps 获取 API 路由......” -

(Next.js 9.3.6)


Cir*_*四事件 9

里卡多·卡内拉斯 (Ricardo Canelas) 所说的话更加明确:

当您这样做时next build,下一步将遍历它检测到可以静态构建的所有页面,即所有未定义getServerSideProps,但可能定义getStaticProps和 的页面getStaticPaths

为了构建这些页面,Next 调用getStaticPaths来决定要构建哪些页面,然后getStaticProps获取构建页面所需的实际数据。

现在,如果您执行 API 调用(getStaticPaths例如getStaticProps,对 JSON 后端 REST 服务器),那么这将由next build.

但是,如果您已将前端和后端很好地集成到单个服务器中,那么您很可能刚刚退出了开发服务器 ( next dev),现在正在尝试构建以查看部署前的健全性检查是否仍然有效。

因此,在这种情况下,构建将尝试访问您的服务器,但它不会运行,因此您会收到类似的错误。

getStaticPaths正确的方法是,您应该直接从or进行数据库查询,而不是通过 REST API getStaticProps。无论如何,该代码永远不会在客户端上运行,只能在服务器上运行,它也比对 API 进行无用的访问(然后间接调用数据库)要稍微高效一些。我在这里有一个演示:https://github.com/cirosantilli/node-express-sequelize-nextjs-realworld-example-app/blob/b34c137a9d150466f3e4136b8d1feaa628a71a65/lib/article.ts#L4

export const getStaticPathsArticle: GetStaticPaths = async () => {
  return {
    fallback: true,
    paths: (await sequelize.models.Article.findAll()).map(
      article => {
        return {
          params: {
            pid: article.slug,
          }
        }
      }
    ),
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意在该示例中, 和getStaticPathsgetStaticProps这里是用于重用的通用 HoC,另请参阅:未找到模块:无法解析 Next.js 应用程序中的“fs”)通过sequelize ORM 执行直接数据库查询,并且不执行任何 HTTP调用外部服务器 API。

然后,您应该仅在初始页面加载后(即来自useEffectet al.)而不是从getStaticPaths或进行来自浏览器上的 React 组件的客户端 API 调用getStaticProps。顺便说一句,请注意,如以下所述:What is the Difference Betweenfallback false vs true vsblocking of getStaticPaths with and without revalidate in Next.js SSR/ISR? 尽可能减少客户端调用并在服务器上预渲染大大降低了应用程序的复杂性。