【问题标题】:Why is my MEVN app only showing the backend when deploying to Heroku?为什么我的 MEVN 应用在部署到 Heroku 时只显示后端?
【发布时间】:2026-02-03 18:40:02
【问题描述】:

我的应用目前通过 Heroku 在线部署,但它显示的是后端服务器而不是我的 Vue 应用。

注意:我在 app.js 中有一个 if 语句,它只在生产环境中提供文件。我删除了 if 语句以查看应用程序是否会出现没有环境条件。它没有用。

我的 express 目录中还有一个名为 dist 的缩小 Vue js 文件夹。

更新

我使用的 heroku 方法是 Heroku Git Cli

$ cd my-project/
$ git init
$ heroku git:remote -a testingew
$ git add .
$ git commit -am "make it better"
$ git push heroku master

这是我看到的,是后端对“/”路由的响应。代码在 app.js 中

app.js 完整代码

const serveStatic = require("serve-static");
const path = require("path");
const express = require("express");
const app = express();
const userRoutes = require("./routes/user");
const budgetRoutes = require("./routes/budget");
const profileRoutes = require("./routes/profile");
require("dotenv/config");
const port = process.env.PORT || 3000;
const cors = require("cors");
const morgan = require("morgan");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const cookieParser = require("cookie-parser");
const sessions = require("express-session");
const MongoStore = require("connect-mongo")(sessions);
const passport = require("passport");
const passportSetup = require("./config/passport.js");

//Log when making request
app.use(morgan("combined"));

//Parse body for post request
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

var corsOption = {
  origin: true,
  methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
  credentials: true
};

app.use(cors(corsOption));

app.use(
  sessions({
    secret: process.env.SESSION_COOKIEKEY,
    saveUninitialized: false,
    resave: false,
    store: new MongoStore({
      mongooseConnection: mongoose.connection
    }),
    cookie: {
      // secure: true,
      maxAge: 86400000
    }
  })
);

//Initialize passport
app.use(passport.initialize());
app.use(passport.session());

//Automatic route placer
app.use("/auth", userRoutes);
app.use("/api/budget", budgetRoutes);
app.use("/api/profile", profileRoutes);
app.get("/", (req, res) => {
  res.send("App is on");
});

//404 error and pas to error handler
app.use((req, res, next) => {
  const error = new Error("An error has occured");
  error.status = 404;
  next(error);
});

//Error handler
app.use((error, req, res, next) => {
  //Respond Client
  res.status(error.status || 500);
  res.json({
    error: {
      message: error.message
    }
  });
  console.log(error.message);
});

//Mongo connection
mongoose.connect(
  process.env.DB_CONNECTION,
  {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useFindAndModify: false
  },
  () => console.log("connected to mongo atlas")
);

//Handle production
app.use(express.static(path.join(__dirname, "dist")));

// Redirect all requests to `index.html`
app.get("/*", (req, res) => {
  res.sendFile(path.join(__dirname, "dist", "index.html"));
});
//Start app
app.listen(port, () => {
  console.log(`Server is on port ${port}`);
});

Vue 路由器

注意:如果这意味着什么,我也在组件中使用路由导航保护

import Vue from "vue";
import VueRouter from "vue-router";

//import axios from "axios";

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "login",
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () =>
      import(/* webpackChunkName: "about" */ "../views/Login.vue")
  },
  {
    path: "/userprofile",
    name: "userProfile",
    component: () => import("../views/userProfile.vue"),
    meta: {
      requireAuth: true
    }
  },
  {
    path: "/budgetform",
    name: "form",
    component: () => import("../views/budgetForm.vue"),
    meta: {
      requireAuth: true
    }
  },
  {
    path: "/mybudget",
    name: "myBudget",
    component: () => import("../views/myBudget.vue"),
    meta: {
      requireAuth: true
    }
  }
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes
});

export default router;

Express的文件目录

希望对你有帮助

【问题讨论】:

    标签: node.js express vue.js heroku vuejs2


    【解决方案1】:

    编辑

    根据您的编辑显示您的 Express 应用,您需要删除它们之间的所有内容

    app.use("/api/profile", profileRoutes);
    

    Mongo。如果您在路线上执行其他操作,该应用程序将无法运行。 “应用程序已打开”和错误检查内容阻止了您的应用程序。我不认为你的意思是在每条路线上都运行错误,但这就是正在发生的事情。我建议浏览一些 Express 教程并从头开始尝试理解为什么它不起作用。

    原创

    尝试将app.listen 上面的所有内容替换为:

    // Serve static assets
    app.use(express.static(path.join(__dirname, 'dist')));
    
    // Redirect all requests to `index.html`
    app.get('/*', (req, res) => {
      res.sendFile(path.join(__dirname, 'dist', 'index.html'));
    })
    

    您的通配符匹配错误,只会匹配以点开头的文件路径,path.join 使用不正确,应该没有斜线文字。我也改变了一些其他的语法。如果这不能完全解决问题,则存在许多超出此问题范围的错误可能性:

    1) 目录结构 2) .gitignore 3)Vue路由器 4) package.json start 脚本

    【讨论】:

    • 您好,感谢您的帮助。我尝试将上面的代码替换为上面的代码,但没有任何改变。我可以用更多信息编辑我的问题
    • 如果没有别的,404 错误现在应该重定向到index.html,而不是以前。问题: 1) 当您查看应用程序时,您看到了什么? 2)你能展示你的vue-router吗? 3) 您使用的是哪种 Heroku 部署方法?
    • 感谢您的帮助。我会做更多的研究,因为我认为错误处理是 Express 应用程序的重要组成部分
    • 当然。每个请求只能发送一个响应。您正在为根请求发送“应用程序已打开”,因此没有其他任何事情发生。如果您删除了它,那么错误检查也会遇到同样的问题,即在每条路线上发回一条错误消息,而不是交付您的实际文件或应用程序。您的代码需要确保在发送错误之前存在实际错误,而不是每次都这样做。所有这些东西都妨碍了为您的应用程序提供服务。在 Heroku 上尝试之前先尝试让它在本地工作。
    • 啊,我明白了,所以应用程序默认为“应用程序已打开”而不是任何其他请求。在开发中发送“app is on”是可以的,因为我还没有将所有请求重定向到 dist/index.html。
    最近更新 更多