2021 年使用 Vercel 托管 MERN 应用程序(不使用 Next.js)

Jac*_*eph 3 express reactjs mern serverless vercel

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

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

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

MrJ*_*eja 8

根据你的评论你的文件结构应该是这样的

// + 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

Run Code Online (Sandbox Code Playgroud)

步骤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
}
Run Code Online (Sandbox Code Playgroud)

步骤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>
Run Code Online (Sandbox Code Playgroud)

第 3 步 - 构建你的反应

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

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

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

Run Code Online (Sandbox Code Playgroud)

步骤 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'));
  })
}
Run Code Online (Sandbox Code Playgroud)

第 5 步 - 在存储库的根级别(即您的案例main目录中)添加 vercel.json

{
  "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"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

最后你的文件结构看起来像这样

// + 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

Run Code Online (Sandbox Code Playgroud)

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

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

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

快乐编码:)