NextJS API | 应用程序可以在部署和开发模式下运行,但当我运行下一个构建时却不能运行 | 经济拒绝

Sil*_*e87 4 javascript build reactjs next.js vercel

描述错误

我使用 NextJS 构建了一个具有内部 API 的应用程序,并使用 getStaticProps 方法来查询 API。

您可以在此处找到已部署的应用程序:https://tailor-challenge.vercel.app/

还有 github 存储库:在此处输入链接描述

该应用程序在开发模式下运行良好,我在 Vercel 中进行的部署也可以运行。但是当我运行下一个构建命令时,出现以下错误:

Build error occurred
FetchError: request to http://localhost:3000/api/restaurants failed, reason: connect ECONNREFUSED 127.0.0.1:3000
    at ClientRequest.<anonymous> (/home/silinde87/Jobs/tailor/TailorChallenge/node_modules/node-fetch/lib/index.js:1461:11)
    at ClientRequest.emit (node:events:376:20)
    at Socket.socketErrorListener (node:_http_client:474:9)
    at Socket.emit (node:events:376:20)
    at emitErrorNT (node:internal/streams/destroy:188:8)
    at emitErrorCloseNT (node:internal/streams/destroy:153:3)
    at processTicksAndRejections (node:internal/process/task_queues:80:21) {
  type: 'system',
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED'
}
info  - Collecting page data .npm ERR! code 1
npm ERR! path /home/silinde87/Jobs/tailor/TailorChallenge
npm ERR! command failed
npm ERR! command sh -c next build 
Run Code Online (Sandbox Code Playgroud)

NextJS 内部 API

/api/restaurants/index.js

Build error occurred
FetchError: request to http://localhost:3000/api/restaurants failed, reason: connect ECONNREFUSED 127.0.0.1:3000
    at ClientRequest.<anonymous> (/home/silinde87/Jobs/tailor/TailorChallenge/node_modules/node-fetch/lib/index.js:1461:11)
    at ClientRequest.emit (node:events:376:20)
    at Socket.socketErrorListener (node:_http_client:474:9)
    at Socket.emit (node:events:376:20)
    at emitErrorNT (node:internal/streams/destroy:188:8)
    at emitErrorCloseNT (node:internal/streams/destroy:153:3)
    at processTicksAndRejections (node:internal/process/task_queues:80:21) {
  type: 'system',
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED'
}
info  - Collecting page data .npm ERR! code 1
npm ERR! path /home/silinde87/Jobs/tailor/TailorChallenge
npm ERR! command failed
npm ERR! command sh -c next build 
Run Code Online (Sandbox Code Playgroud)

/api/restaurants/[id].js

export default function handler(req, res) {
    const { method } = req;
    
    switch (method) {
        case 'GET':
            getRestaurants();
            break;
        default:
            res.status(405).end(`Method ${req.method} Not Allowed`);
    }

    function getRestaurants() {
        const restaurants = data;
        res.status(200).json(restaurants);
    }
}
Run Code Online (Sandbox Code Playgroud)

来自 NextJS 的页面

pages/index.js <-- 我在哪里获取餐厅列表

export default function handler(req, res) {
    const { id } = req.query;
    const { method } = req;

    switch (method) {
        case 'GET':
            getRestaurantById();
            break;
        default:
            res.status(405).end(`Method ${req.method} Not Allowed`);
    }

    function getRestaurantById() {
        const restaurants = data.find((el) => el.id.toString() === id.toString());
        if (restaurants) res.status(200).json(restaurants);
        else res.status(405).end(`There is no Restaurant with id: ${id}`);
    }
}
Run Code Online (Sandbox Code Playgroud)

页面/[id].js

export async function getStaticProps() {
    const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants`);
    const restaurants = await res.json();

    if (!restaurants) {
        return {
            notFound: true,
        };
    }

    return {
        props: {
            restaurants,
        },
    };
}
Run Code Online (Sandbox Code Playgroud)

tpe*_*aki 6

我从官方文档中引用了这句话,链接如下:

\n
\n

注意:您不应使用 fetch() 调用 >getStaticProps 中的 API 路由。相反,直接导入>您的 API 路由中使用的逻辑。您可能需要针对此方法稍微重构您的代码。

\n

从外部 API 获取就可以了!

\n
\n

https://nextjs.org/docs/basic-features/data-fetching

\n

基本上是因为 getStaticProps 或 getStaticPaths 中的代码永远不会在浏览器中执行,因此您可以安全地直接在那里调用数据源。

\n

另外,失败的发生是因为应用程序在构建时未运行,因此 localhost api 不可用。您可以通过在另一个终端窗口中通过 \xe2\x80\x99yarn dev\xe2\x80\x99 或 \xe2\x80\x99npm run dev\xe2\x80\x99 运行应用程序来确认这一点,并在另一个终端窗口中构建应用程序。这样它应该可以很好地构建,但不推荐这样做。我将重构代码,以便在这些 getStaticProps 和 getStaticPaths 函数中不会获取此应用程序的 api。

\n

getServerSideProps 也是如此,它也只在服务器上运行,因此您也不应该在那里获取 api。只有浏览器才应该提取 api,例如,如果您希望用户能够将一些数据发布到应用程序。

\n