Heroku 部署因反应和下一个 js 而失败

Heroku deploy fails with react and next js

我的 react/next js 应用程序在我的本地主机上运行良好(零 errors/warnings),但不知何故无法在 Heroku 上部署。 部署时,我始终收到相同的错误,指出我的 posts 数组(在 pages/landing.js 中)未定义。

我尝试按照日志中的建议调试和创建支持票证,但 Heroku 支持无法提供帮助。

我将日志语句添加为日志 1,2,帖子是什么,3 并且在部署日志中,我只看到 "log 3 landing js undefined" 所以它以某种方式跳过了 API 调用和客户端-来自 pages.index.js

的旁白

我的代码是这样的:

// pages/index.js
import React from "react";
import Landing from "./landing";
import Layout from "../src/components/layout";
import fetch from "isomorphic-unfetch";
import Error from "next/error";

const Index = ({ posts }) => (
  <Layout>
    <div>
      {console.log("what are the posts???", posts)}
      <Landing posts={posts} />
    </div>
  </Layout>
);

export default Index;

Index.getInitialProps = async () => {
  console.log("log 1");
  const res = await fetch("http://localhost:3000/api/posts");

  const json = await res.json();
  console.log("log 2 what is json", json);
  return { posts: json.posts };
};

//pages/landing.js
import React from "react";
import Navigation from "../src/components/navigation";
import Layout from "../src/components/layout";
import Link from "next/link";
import ReactMarkdown from "react-markdown";

const Landing = ({ posts }) => {
  return (
    <Layout>
      <Navigation />
// ...
      {console.log("log 3 landing js ", posts)}
            {posts.map(post => (
              <h1>post.title</h1>
            ))}
      <Navigation />
    <Layout>
export default Landing;

//package.json
{
  "version": "1.0.0",
  "private": true,
  "engines": {
    "node": "12.2.0",
    "npm": "6.4.1",
    "yarn": "1.13.0"
  },
  "dependencies": {
    "bootstrap": "^4.4.1",
    "isomorphic-unfetch": "^3.0.0",
    "next": "^9.1.4",
    "raw-loader": "^4.0.0",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-markdown": "^4.2.2",
    "react-scripts": "3.2.0"
  },
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start -p $PORT"
  },
  "eslintConfig": {
    "extends": "react-app"
  }
}
// next.config.js

module.exports = {
  webpack: config => {
    config.module.rules.push({
      test: /\.md$/,
      use: "raw-loader"
    });

    return config;
  }
};

最后,Heroku 部署日志:

-----> Node.js app detected

-----> Creating runtime environment

       NPM_CONFIG_LOGLEVEL=error
       NODE_ENV=production
       NODE_MODULES_CACHE=true
       NODE_VERBOSE=false

-----> Installing binaries
       engines.node (package.json):  12.2.0
       engines.npm (package.json):   6.4.1
       engines.yarn (package.json):  1.13.0

       Resolving node version 12.2.0...
       Downloading and installing node 12.2.0...
       Bootstrapping npm 6.4.1 (replacing 6.9.0)...
       npm 6.4.1 installed
       Resolving yarn version 1.13.0...
       Downloading and installing yarn (1.13.0)...
       Installed yarn 1.13.0

-----> Installing dependencies
       Installing node modules (yarn.lock)
       yarn install v1.13.0
       [1/4] Resolving packages...
       [2/4] Fetching packages...
       info fsevents@1.2.9: The platform "linux" is incompatible with this module.
       info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation.
       info fsevents@2.0.7: The platform "linux" is incompatible with this module.
       info "fsevents@2.0.7" is an optional dependency and failed compatibility check. Excluding it from installation.
       [3/4] Linking dependencies...
       warning " > bootstrap@4.4.1" has unmet peer dependency "jquery@1.9.1 - 3".
       warning " > bootstrap@4.4.1" has unmet peer dependency "popper.js@^1.16.0".
       warning " > raw-loader@4.0.0" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
       warning "react-scripts > @typescript-eslint/eslint-plugin > tsutils@3.17.1" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta".
       [4/4] Building fresh packages...
       Done in 52.24s.

-----> Build
       Running build (yarn)
       yarn run v1.13.0
       $ next build
       Creating an optimized production build...
       Attention: Next.js now collects completely anonymous telemetry regarding usage.
       This information is used to shape Next.js' roadmap and prioritize features.
       You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
       https://nextjs.org/telemetry


       Compiled successfully.

       Automatically optimizing pages...
       log 3 landing js  undefined
Error occurred prerendering page "/landing": TypeError: Cannot read property 'map' of undefined
    at Landing (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/.next/server/static/ATrNApXPLQXluLPvZMJ2m/pages/landing.js:4246:32)
    at d (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:498)
    at Za (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:39:16)
    at a.b.render (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:476)
    at a.b.read (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:18)
    at renderToString (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:54:364)
    at render (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/next/dist/next-server/server/render.js:81:16)
    at Object.renderPage (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/next/dist/next-server/server/render.js:323:20)
    at /tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/.next/server/static/ATrNApXPLQXluLPvZMJ2m/pages/_document.js:2046:21
    at Generator.next (<anonymous>)
> Build error occurred
Error: Export encountered errors
    at _default (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/next/dist/export/index.js:15:788)
    at processTicksAndRejections (internal/process/task_queues.js:89:5)
    at async build (/tmp/build_e6fcf8d3b8da4774fe2ba078e3d46384/node_modules/next/dist/build/index.js:20:145)
error Command failed with exit code 1.
       info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
-----> Build failed

       We're sorry this build is failing! You can troubleshoot common issues here:
       https://devcenter.heroku.com/articles/troubleshooting-node-deploys

       If you're stuck, please submit a ticket so we can help:
       https://help.heroku.com/

       Love,
       Heroku

 !     Push rejected, failed to compile Node.js app.
 !     Push failed

由于您的 landing 页面没有 getInitialProps,next.js 正在尝试预呈现它,因此 post 未定义。您可以做的一件事是将 landing 移动到组件中。

如果您需要在每个页面上使用 posts,您可以在自定义应用中使用 getInitialProps,就像 in the docs

中描述的那样

下面其实是另一个问题的回答

我想,在您的 Heroku 实例上使用 localhost:3000 不太正确。相反,您可以从请求 headers 中获取 api 页面的 url,因此您的 getInititalProps 看起来类似于:

Index.getInitialProps = async ctx => {
  if (ctx.req) {
    const host = ctx.req.headers['x-forwarded-host'];
    const proto = ctx.req.headers['x-forwarded-proto'];
    const port =  ctx.req.headers['x-forwarded-port'];

    const res = await fetch(`${proto}//${host}:${port}/api/posts`);

    const json = await res.json();
    return { posts: json.posts };
  } else {
    // otherwise we are in the browser
    const res = await fetch(`/api/posts`);

    const json = await res.json();
    return { posts: json.posts };
  }
}

我在这里查过:https://spectrum.chat/next-js/general/calling-pages-api-directly-in-ssr-getinitialprops~8416c24b-19dc-46eb-aab7-8943a0c4a92e

为了在 heroku 中成功部署 nextjs 应用程序,您需要在 package.json 文件

中做一点小修改

将启动命令更新为:"start": "next start -p $PORT"

之前:

"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start"
}

之后:

"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start -p $PORT"
}