为啥我的 Next.js s-s-r api 调用 Error: The default export is not a React Component in page:"/api/twil

Posted

技术标签:

【中文标题】为啥我的 Next.js s-s-r api 调用 Error: The default export is not a React Component in page:"/api/twilio" at Object.renderToHTML & 我该如何工作?【英文标题】:Why does my Next.js s-s-r api call Error: The default export is not a React Component in page:"/api/twilio" at Object.renderToHTML & how do I make work?为什么我的 Next.js s-s-r api 调用 Error: The default export is not a React Component in page:"/api/twilio" at Object.renderToHTML & 我该如何工作? 【发布时间】:2021-12-28 21:05:31 【问题描述】:

我有一个 Next.js 应用程序,它在 pages 目录中具有按预期呈现的 React 组件。该应用程序是为 Rails 后端 api 构建的,并且每天都在正确使用该后端。我正在尝试向应用程序添加 twilio 视频聊天。我按照所有文档中的说明创建了一个 /api 目录。当我尝试调用此 api 以获取一个模拟示例来测试 api 时,我在终端 Error: The default export is not a React Component in page: "/api/twilio" at Object.renderTohtml (/home/application_in_question/node_modules/next-server/dist/server/render.js:117:19) 中收到错误消息 我还在浏览器中得到Failed to load resource: the server responded with a status of 500 (Internal Server Error)。我不是构建这个应用程序的团队的一员,所以我不确定为什么我不能添加这个 Next.js api。 api是Next的卖点,据说是内置在框架中的。

我得到这个错误是我只是把路由放在浏览器的地址栏中,但我也从文件 api 调用中得到它。

pages/twilio/index.js

  const handleFetchPosts = async () =>  
  debugger
  const tokenResponse = await fetch("/api/twilio"); 
  debugger
  const tokenData = await tokenResponse.json(); 
  debugger
  setToken(tokenData);
  ; 

package.json 部分

"next": "^8.1.0",
"next-auth": "^1.8.5",
"next-compose-plugins": "^2.2.0",
"next-redux-wrapper": "^2.0.0",
"next-routes": "^1.4.2",
"next-seo": "^1.11.2",
"node-sass": "^4.12.0",

pages/api/twilio/index.js

console.log("running api")
const handler = (req, res) => 
    return res.json( hello: 'world!' );
  ;
  export default handler;

next.config.js

 const  withPlugins, optional  = require('next-compose-plugins')
// eslint-disable-next-line import/no-extraneous-dependencies
const  PHASE_PRODUCTION_BUILD  = require('next-server/constants')
const sass = require('@zeit/next-sass')
const  requireEnvVar  = require('./lib/utils')


  Custom Next.js Configuration
  @see https://nextjs.org/docs#custom-configuration

 const nextConfig = 

  Runtime configuration
  @see https://nextjs.org/docs#exposing-configuration-to-the-server--client-side

  publicRuntimeConfig: 
// Will be available on both server and client
    apiUrl: requireEnvVar('API_SERVER'),
    googleApiKey: requireEnvVar('GOOGLE_API_KEY'),
    stripeApiKey: requireEnvVar('STRIPE_PUBLISHABLE_KEY'),
    instantPayFee: requireEnvVar('INSTANT_PAY_FEE'),
  ,

   Disable file-system routing
  @see https://nextjs.org/docs#disabling-file-system-routing
 
  **useFileSystemPublicRoutes: true,**

    Custom webpack config
    @see https://nextjs.org/docs#customizing-webpack-config

   webpack(config,  webpack ) 

  Only load specific locales for moment.js
  @see https://***.com/a/25426019/956688
 
    config.plugins.push(
      new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/)
    )

    return config
  ,



     Load multiple plugins with next-compose-plugins
     @see https://github.com/cyrilwanner/next-compose-plugins

    module.exports = withPlugins(
      [
        [sass],

      Analyzing the webpack bundle
         @see https://github.com/zeit/next-plugins/tree/master/packages/next-bundle-analyzer
 
       Load @zeit/next-bundle-analyzer as an optional plugin only during production build
       @see https://github.com/cyrilwanner/next-compose-plugins#optional-plugins
       @see https://github.com/cyrilwanner/next-compose-plugins#phases-array
 
        [
      // eslint-disable-next-line global-require,import/no-extraneous-dependencies
      optional(() => require('@zeit/next-bundle-analyzer')),
      
    analyzeServer: ['server', 'both'].includes(process.env.BUNDLE_ANALYZE),
        analyzeBrowser: ['browser', 'both'].includes(
          process.env.BUNDLE_ANALYZE
        ),
        **bundleAnalyzerConfig: 
          server: 
            analyzerMode: 'static',
            reportFilename: '../../bundles/server.html',
          ,
          browser: 
            analyzerMode: 'static',
                reportFilename: '../bundles/client.html',
              ,
            **,
          ,
          [PHASE_PRODUCTION_BUILD],
        ],
      ],
  nextConfig
)`

正如您在上面看到的那样,我之前的团队将 useFileSystemPublicRoutes 设置为 false。我已经做到了。

当我尝试在反应页面中获取 api 或在浏览器中对我使用代码创建的 api/index.js 文件使用获取请求时

`

 console.log("running api")
                                                                                           
const handler = (req, res) => 

    return res.json( hello: 'world!' );
    ;
    export default handler;` 

这给出了上面的错误。这是一个非常简单的示例,我在许多在线资源中都看到过,所以我不明白为什么会发生这种情况。

我怎样才能让这个 api 工作???

** 我添加了 ** 是为了突出我认为可以提供帮助的部分。我已经将 useFileSystemPublicRoutes 设置为 true。

【问题讨论】:

那个 api 文件在你的项目文件夹结构中在哪里? 我在 pages/api/twilio/index.js 文件中有它。我还有一个 pages/api/twilio.js 文件,其中包含相同的代码 sn-p 只是为了让它运行。两个例子都不起作用:( 这看起来确实是一个正确的结构。 Next 应该将 pages/api 中的文件视为 API 端点,而不是“页面”,但在您的情况下,它认为它是一个页面。您使用的是哪个版本的 Next? "next": "^8.1.0" 来自 package.json。 IMO 之前的团队不打算使用下一个 api。我只是想让它再次工作。 看来是这样。快速浏览 npmjs 上的版本历史似乎表明 API 路由是在 9.0 版中添加的 【参考方案1】:

您可以在评论线程中阅读 Next@8 是在将 API 路由添加到框架之前。我最终使用了一种解决方法,我使用了 rails 后端服务器。下一个版本 9+ 具有 api 路由,其中​​ pages/api 目录中的任何文件都被视为服务器后端 api 文件。 Next 8 是把 pages/api/file 当作前端网页文件来寻找 react。

【讨论】:

以上是关于为啥我的 Next.js s-s-r api 调用 Error: The default export is not a React Component in page:"/api/twil的主要内容,如果未能解决你的问题,请参考以下文章

如何实现redux-toolkit和next,js又不丢s-s-r

为啥在将 next.js 与环境变量一起使用时我的 API 密钥可见?

在 s-s-r 和动态 URL 中使用 Apollo 进行查询 (Next.js)

如何在 Next.js SSG 或 s-s-r 中使用 Redux 工具包调度?

Next.js 与 FortAwesome 和 s-s-r

Apollo Client + Next.js 不发送非 s-s-r 请求