首页 > 解决方案 > Mongodb、Reactjs、Express、Node js Heroku 部署显示空白页和 404 错误。在本地工作

问题描述

我的应用程序在本地运行。路线通过邮递员工作,并且 DB 被击中(如 Robo 3t 所示)。Heroku 部署构建只是为了在应用程序启动时显示一个空白页面。控制台显示如下: 在此处输入图像描述

下面是我的代码:

服务器.js

const express = require("express");
const app = express();
const path = require("path");
const mongoose = require("mongoose");
const routes = require("./routes");
const bodyParser = require("body-parser");
const cors = require ('cors');
require('dotenv').config()


const PORT = process.env.PORT || 3001;


// Connect to the Mongo DB
mongoose.connect(
    process.env.MONGODB_URI || "mongodb://localhost/sfwReactPortfolio",
    {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  // useCreateIndex: true,
  useFindAndModify: false
}
);



mongoose.set('useCreateIndex', true);

// mongoose.createConnection(
//   process.env.MONGODB_URI || "mongodb://localhost/sfwReactPortfolio", 
//   {   
//   useUnifiedTopology: true,
//   useNewUrlParser: true,
//   useFindAndModify: false,
// });

// /** */ const Book = mongoConnection.model('Book', bookSchema /*, 'COLLECTION_NAME'*/);

const mongoose_db = mongoose.connection;

// Define middlewares here for parsing req.body:
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cors());


// Configure body parsing for AJAX requests
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

// Serve up static assets
if (process.env.NODE_ENV === "production") {
  app.use(express.static("client/build"));
}


// Currently serving static assets
app.use(express.static(path.join(__dirname, "public")));

// Add routes, both API and view
app.use(routes);

// // Verifies connection to db on desired port. 
mongoose_db.once("open", function() {
  app.listen(PORT, () => {console.log("Server Listening on Port", PORT)});
})

// // Throws error on failed db connection check. 
mongoose_db.on("error", function() {
  console.error("database failed to open");
})

路线 - index.js

const express = require("express");
const router = express.Router();
const nodemailer = require("nodemailer")
const ContactForm = require('../models/contactForm');

  router.post("/api/messages", (req,res)=>{
    let data = req.body
    let smtpTransport = nodemailer.createTransport({
      service:"Gmail",
      port:465,
      auth: {
        user:"sfwportfoliomessages@gmail.com",
        pass: "git4tm3!"
      }
    });
  
  let mailOptions = {
    from: data.email,
    to:"sfwportfoliomessages@gmail.com",
    subject: `Message from ${data.firstName}`,
    html:`
    <h3>Information</h3>
    <ul>
    <li>firstName: ${data.firstName}</li>
    <li>lastName: ${data.lastName}</li>
    <li>email: ${data.email}</li>
    </ul>
    <h3>Message</h3>
    <p>${data.message}</p>
  <p>${data.time}</p>
    `
  };
  
  smtpTransport.sendMail(mailOptions, (error, res)=>{
    if(error) {
      res.send(error)
    } else {
      res.send("Success")
    }
  })
  
  smtpTransport.close();

  ContactForm.create(req.body,
    function (err, response) {
      console.log(`response: ${response}`)
      if (err){
        console.log(err)
        return
      }
      res.json(response)
    }
  )
  })

   module.exports = router;

模型架构

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const ContactSchema = new Schema ({
    firstName: {type: Schema.Types.String},
    lastName: {type: Schema.Types.String},
    email: {type: Schema.Types.String},
    message: {type: Schema.Types.String},
    pubDate: {
        type: Schema.Types.Date,
        default: Date.now,
      },
})

const ContactFrom = mongoose.model("ContactForm", ContactSchema);

module.exports = ContactFrom;

前端 App.js

import React from 'react';
import {BrowserRouter as Router, Switch, Route} from "react-router-dom"
import Header from "../src/components/header"
import Footer from "../src/components/footer"
import Portfolio from "../src/pages/portfolio"
import About from "../src/pages/about"
import Contact from "../src/pages/contact"



function App() {
  return (
    <div className="App container-fluid container-sm">
      <Router>
      <Header/>
        <Switch>
          <Route exact path={["/about","/", "/hw-unit20-reactPortfolio"]}>
            <About />
          </Route>
          <Route  path="/contact">
            <Contact />
          </Route>
          <Route exact path="/portfolio">
            <Portfolio />
          </Route>
        </Switch>
    </Router>
      <Footer/>
    </div>
  );
}

export default App;

清单.json

    {
  "short_name": "React App",
  "name": "Create React App Sample",
  "start_url": "./index.html",
  "display": "standalone",
  
  "theme_color": "#000000",
  "background_color": "#ffffff"
}

后端包.json

{
  "name": "hw-unit20-reactPortfolio",
  "version": "1.0.0",
  "engines": {
    "node": "12.x"
  },
  "description": "portfolio v4 created with REACT",
  "main": "server.js",
  "dependencies": {
    "body-parser": "^1.19.0",
    "concurrently": "^5.2.0",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "if-env": "^1.0.4",
    "moment": "^2.27.0",
    "mongodb": "^3.5.9",
    "mongoose": "^5.9.19",
    "nodemailer": "^6.4.10",
    "nodemon": "^2.0.4",
    "path": "^0.12.7",
    "react-router": "^5.2.0",
    "react-router-dom": "^5.2.0"
  },
  "devDependencies": {},
  "scripts": {
    "start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
    "start:prod": "node server.js",
    "start:dev": "concurrently \"nodemon --ignore 'client/*'\" \"npm run client\"",
    "client": "cd client && npm run start",
    "install": "cd client && npm install",
    "build": "cd client && npm run build",
    "heroku-postbuild": "npm run build"
  }
}

客户端包.json

    {
  "name": "app",
  "homepage": "https://SpencerFalor-Ward.github.io/hw-unit20-reactPortfolio",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:3001/",
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "axios": "^0.19.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "predeploy": "npm run build"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

索引.html

<!DOCTYPE html>
<html lang="en-us">

    <!--Header containg site tab title, character set, link to CSS sheet-->
    <head>
        <meta charset="UTF-8">
        <!-- <link rel="stylesheet" type="text/css" href="../src/assets/css/reset.css"> -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
        <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
        <link rel="stylesheet" type="text/css" src="./assets/css/styles.css">
        <title>SFW Digital Buisiness Card</title>
    </head>

<body>
    <div id="root"></div>
</body>
</html>

文件结构 在此处输入图像描述

我很感激这里的任何帮助!

标签: node.jsreactjsmongodbexpressheroku

解决方案


我找到了答案!使用本指南https://coursework.vschool.io/deploying-mern-with-heroku/引导我将以下代码行添加到我的 server.js 中:

app.use(express.static(path.join(__dirname, "client", "build")))

在我已经存在的范围内

if (process.env.NODE_ENV === "production") {
  app.use("<git repo name>", express.static("client/build"));
  
}

我添加了

app.get("*", (req, res) => {
    res.sendfile(path.resolve(__dirname, "client", "build", "index.html"));
})

我还确保将上面的“if.....”代码放在包含我的“app.listen ....”的代码之前

我的仓库在这里:https ://github.com/SpencerFalor-Ward/hw-unit20-reactPortfolio

虽然我之前在没有这里使用的代码的情况下成功地将 MERN 应用程序部署到 Heroku,但这次是需要的。


推荐阅读