【问题标题】:Hosting a MERN application with Vercel in 2021 (without Next.js)2021 年使用 Vercel 托管 MERN 应用程序(无 Next.js)
【发布时间】:2021-11-17 11:38:18
【问题描述】:

我一直在使用 Vercel 来托管多个 React Web 应用程序,这非常棒!最近,我用后端(Express.js 和 MongoDB Atlas)升级了一个现有项目,我也想在那里托管它。

在我的机器上,MongoDB 服务器和所有 CRUD 路由都在 localhost:5000 上顺利运行,但我想知道如何将其添加到 Vercel 部署中。 Vercel 的文档侧重于无服务器部署,虽然我不介意在必要时重写我的后端,但我想知道是否有更简单的解决方案来添加服务器/数据库。

MERN 堆栈仍然比较流行,所以我想很多开发人员已经找到了托管此类项目的方法。如果有人可以提供帮助,我将不胜感激!

【问题讨论】:

  • 提供你的代码结构。即,您的 server.js 文件和客户端位于何处?我在没有 next.js 的情况下将 MERN 部署到 vercel。
  • 当然!在主项目目录中,有一个用于后端的文件夹(模型、路由、server.js)和另一个用于 src 的文件夹(页面、组件等)。两个文件夹处于同一级别。这有帮助吗?
  • 我会在几分钟后发布解决方案
  • 那太棒了!非常感谢!

标签: reactjs express serverless mern vercel


【解决方案1】:

根据您的评论,您的文件结构应如下所示

// + refer as close folder
// - refer as open folder
// > refer as file

main

  - backend
    + models
    + routes
    > package.json
    > package-lock.json
    > server.js

  - frontend
    + public
    - src
      + pages
      + components
    > package.json
    > package-lock.json

第 1 步 - 编辑前端 package.json
添加主页

{
  // initially add link whatever you suppose to be link of your site
  // then after deploying to vercel, you get the exact link
  // then replace it with vercel link in "homepage" key

  "homepage": "https://awesome-app.vercel.app",
  "name": "awesome-app",
  "version": "1.0.0,
  "private": true,
  ...rest of your frontend package.json file
}

第 2 步 - 添加基本名称

// you wrapped your app with either BrowserRouter or HashRouter
// add basename prop so it refer to your package.json homepage
// if your route are '/awesome-route' then is converted to
// https://awesome-app.vercel.app/awesome-route

<BrowserRouter basename='/'>    // or HashRouter
  <Switch>
    ...your routes
  </Switch>
</BrowserRouter>

第 3 步 - 构建您的反应

当且仅当您更改前端代码时,您必须每次在部署之前构建您的前端

那么你的前端应该如下所示

  - frontend
    + build    // build folder at root of your frontend
    + public
    - src
      + pages
      + components
    > package.json
    > package-lock.json

第 4 步 - 更改您的 server.js 文件
应该如下所示

// i use "dotenv" package
// in your case must be located at "main > backend > .env"
// see the final file structure at bottom if you don't understand

if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config({path: __dirname+'/.env'});
}

const express = require('express');
const mongoose = require('mongoose');
const path = require('path');

const app = express();
app.use(express.json());

const port = process.env.PORT || 5000;

mongoose.connect(process.env.mongoURI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useCreateIndex: true,
  useFindAndModify: false,

  // remove poolSize or set according to your need
  // read docs before setting poolSize
  // default to 5
  poolSize: 1
})
  .then(() => {
    app.listen(port);
  })

// all your routes should go here
app.use('/some-route', require(path.join(__dirname, 'api', 'routes', 'route.js'));

// static files (build of your frontend)
if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, '../frontend', 'build')));
  app.get('/*', (req, res) => {
    res.sendFile(path.join(__dirname, '../frontend', 'build', 'index.html'));
  })
}

第 5 步 - 添加 vercel.json 在存储库的根级别,即在您的情况下为 main 目录

{
  "version": 2,
  "builds": [
    {
      "src": "./backend/server.js",  // path to your server.js file
      "use": "@vercel/node"
    },
    {
      "src": "./frontend/build",    // path to your build folder
      "use": "@vercel/static"
    }
  ],

  // rewrites any request to api call with server.js
  // now your "app.use('/some-route')" would work as normal as localhost
  // no need to change your codes to serverless way

  // also remember here "/(.*)" is not regular js regex
  // it follows path-to-regex
  // playground link: https://regexr.com

  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/backend/server.js"
    }
  ]
}

最后你的文件结构是这样的

// + refer as close folder
// - refer as open folder
// > refer as file

main

  - backend
    + models
    - routes
      > route.js
    > package.json
    > package-lock.json
    > .env
    > server.js

  - frontend
    - build
      + static
      > manifest.json
      > index.html
    + public
    + src
    > package.json
    > package-lock.json

  > vercel.json   // in your main directory's root

这种方法的缺点是每次将 repo 推送到 github 时都必须构建前端

当且仅当您更改前端代码时,请记住在将您的 repo 推送到 github 之前构建您的前端

还记得在部署后将前端 package.json 文件中的主页 url 替换为 vercel 提供的 url 或您的自定义域 url

快乐编码:)

【讨论】:

  • 我注意到我在猫鼬连接函数中添加了poolSize。删除它或根据您的需要设置。
  • 我已经按照您上面的说明部署了一个 MERN 应用程序,但是它没有正确部署。部署的应用程序为空白并显示控制台日志错误:未捕获的语法错误:意外的令牌'github.com/denskiz/emaily 这是我部署的应用程序:emaily-three.vercel.app
  • 我会检查并尽快回复您
  • 那太棒了!谢谢
  • 现在我收到加载资源失败:服务器响应状态为 404 ()
猜你喜欢
  • 1970-01-01
  • 2021-01-21
  • 2021-10-01
  • 2020-03-23
  • 2021-01-12
  • 2019-10-10
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多