全栈设置(Node.js、React.js 和 MongoDB)

2025-05-26

全栈设置(Node.js、React.js 和 MongoDB)

每当我需要创建一个新项目时,我都倾向于只使用一种语言。所以我喜欢用 JavaScript 来做所有事情,包括 Node.js、Express.js、React.js,而且我特别喜欢使用像 MongoDB 这样的 NoSQL 数据库。

因此我决定分享我从头开始建立这个环境的经验。

首先,让我们创建一个文件夹并为该项目生成 package.json 文件。



$ mkdir node-react-starter
$ cd node-react-starter
$ npm init -y


Enter fullscreen mode Exit fullscreen mode

现在,让我们安装项目依赖项



$ npm install --save express body-parser mongoose


Enter fullscreen mode Exit fullscreen mode

在这个项目中,我们使用Express.js,这是一个非常流行的 Node.js 应用程序框架。body
-parser用于在处理程序之前的中间件中解析传入的请求主体,该中间件位于 req.body 属性下。Mongoose是一个
MongoDB对象建模工具,旨在在异步环境中工作。

然后,安装开发依赖项



$ npm install --save-dev nodemon concurrently


Enter fullscreen mode Exit fullscreen mode

nodemon是一个运行 node.js 应用程序并监听任何文件更改并更新整个应用程序的包。

并发允许我们同时运行多个 npm 命令。

安装依赖项后,您应该得到如下文件:

package.json 文件示例

让我们创建项目结构



$ mkdir models routes
$ touch index.js


Enter fullscreen mode Exit fullscreen mode

打开index.js文件并添加以下代码:



//  index.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

const app = express();

mongoose.Promise = global.Promise;
mongoose.connect(process.env.MONGODB_URI || `mongodb://localhost:27017/node-react-starter`);

app.use(bodyParser.json());

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`app running on port ${PORT}`)
});


Enter fullscreen mode Exit fullscreen mode

此后,您可以在 package.json 文件的脚本下添加一个运行脚本:



"server": "nodemon index.js"


Enter fullscreen mode Exit fullscreen mode

此时,您可以运行后端并成功连接到 mongodb(MongoDB 必须已启动并运行)。您可以像这样运行刚刚创建的脚本:



$ npm run server


Enter fullscreen mode Exit fullscreen mode

让我们启动版本控制来跟踪每个更改。但首先我们需要在项目根目录中添加一个 .gitignore 文件,其内容如下:



node_modules
.idea


Enter fullscreen mode Exit fullscreen mode

然后我们启动版本控制



$ git init
$ git add .
$ git commit -am "first commit"


Enter fullscreen mode Exit fullscreen mode

我们成功创建了后端结构,现在让我们跳转到前端。

现在,让我们使用create-react-app创建一个 React 应用程序。



$ create-react-app client


Enter fullscreen mode Exit fullscreen mode

现在,我们必须在客户端目录中添加依赖项。
这里我们将使用yarn来添加这些依赖项。



$ cd client
$ yarn add axios


Enter fullscreen mode Exit fullscreen mode

axios是一个非常流行的基于承诺的浏览器和 node.js HTTP 客户端。

对于 react-scripts >= 0.2.3

对于当前的 react 版本(以及任何其他 react-scripts > 0.2.3),您只需将以下行添加到客户端目录中的package.json 文件中,这将允许您将前端请求代理到后端应用程序。



"proxy": "http://localhost:5000"


Enter fullscreen mode Exit fullscreen mode

对于 react-scripts < 0.2.3

如果您使用的是旧版本的 react-scripts,则可能需要添加以下配置才能将前端与后端连接起来:



$ cd client
$ yarn add http-proxy-middleware


Enter fullscreen mode Exit fullscreen mode

http-proxy-middleware用于在开发过程中从我们的反应应用程序到后端应用程序创建代理。

现在,我们可以添加配置文件来设置代理,以便从前端向后端应用程序发出请求。
请记住,仅当您使用的是较旧的 React 版本(即 React-scripts < 0.2.3)时才添加此配置。

在目录 /client/src 中,添加文件 setupProxy.js,内容如下



// /client/src/setupProxy.js

const proxy = require('http-proxy-middleware')

module.exports = function(app) {
    app.use(proxy('/api/*', { target: 'http://localhost:5000' }))
}



Enter fullscreen mode Exit fullscreen mode

在项目根目录中的 package.json 中,让我们添加以下运行脚本:



"client": "npm run start --prefix client",
"server": "nodemon index.js",
"dev": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\"",
"start": "node index.js"


Enter fullscreen mode Exit fullscreen mode

现在你的 package.json 文件应该如下所示:



{
  "name": "node-react-starter",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "client": "npm run start --prefix client",
    "server": "nodemon index.js",
    "dev": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\"",
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "mongoose": "^5.6.3"
  },
  "devDependencies": {
    "concurrently": "^4.1.1",
    "nodemon": "^1.19.1"
  }
}



Enter fullscreen mode Exit fullscreen mode

现在您可以使用以下命令运行该项目:



$ npm run dev


Enter fullscreen mode Exit fullscreen mode

这将在端口 5000 上运行后端应用程序,在端口 3000 上运行前端应用程序。
您应该看到 React 应用程序在http://localhost:3000上运行

为了使我们的项目准备好投入生产,我们需要在 index.js 文件中的 app.use(bodyParser.json()) 调用之后添加以下几行:



if (process.env.NODE_ENV === 'production') {
  app.use(express.static('client/build'));

  const path = require('path');
  app.get('*', (req,res) => {
      res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'))
  })

}


Enter fullscreen mode Exit fullscreen mode

这会将所有请求重定向到我们的前端应用程序,除非我们在此代码之前指定任何路由。

现在让我们创建一个简单的交互来查看代理连接的实际操作

在目录 /models 中添加文件 Product.js 并插入以下代码:



// /models/Product.js

const mongoose = require('mongoose');
const {Schema} = mongoose;

const productSchema = new Schema({
    name: String,
    description: String,
})

mongoose.model('products', productSchema);


Enter fullscreen mode Exit fullscreen mode

让我们为后端 API 创建一个路由。

在目录 /routes 中添加文件 productRoutes.js 并插入以下代码:



// /routes/productRoutes.js
const mongoose = require('mongoose');
const Product = mongoose.model('products');

module.exports = (app) => {

  app.get(`/api/product`, async (req, res) => {
    let products = await Product.find();
    return res.status(200).send(products);
  });

  app.post(`/api/product`, async (req, res) => {
    let product = await Product.create(req.body);
    return res.status(201).send({
      error: false,
      product
    })
  })

  app.put(`/api/product/:id`, async (req, res) => {
    const {id} = req.params;

    let product = await Product.findByIdAndUpdate(id, req.body);

    return res.status(202).send({
      error: false,
      product
    })

  });

  app.delete(`/api/product/:id`, async (req, res) => {
    const {id} = req.params;

    let product = await Product.findByIdAndDelete(id);

    return res.status(202).send({
      error: false,
      product
    })

  })

}


Enter fullscreen mode Exit fullscreen mode

现在我们可以在 index.js 中导入模型和路由文件,如下所示:



// /index.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

// IMPORT MODELS
require('./models/Product');

const app = express();

mongoose.Promise = global.Promise;
mongoose.connect(process.env.MONGODB_URI || `mongodb://localhost:27017/node-react-starter`);

app.use(bodyParser.json());

//IMPORT ROUTES
require('./routes/productRoutes')(app);

if (process.env.NODE_ENV === 'production') {
  app.use(express.static('client/build'));

  const path = require('path');
  app.get('*', (req,res) => {
      res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'))
  })

}

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`app running on port ${PORT}`)
});


Enter fullscreen mode Exit fullscreen mode

现在,如果我们运行项目,我们就可以使用 http ://localhost:5000/api/product向我们的简单产品 API 发出请求。
在这里,我们可以获取、插入、更新和删除产品。

回到 React 应用程序,让我们添加一个服务来向后端应用程序发出请求。
在 /client/src 文件夹中创建一个名为 services 的文件夹,并添加一个包含以下内容的文件 productService.js:



//  /client/src/services/productService.js

import axios from 'axios';

export default {
  getAll: async () => {
    let res = await axios.get(`/api/product`);
    return res.data || [];
  }
}


Enter fullscreen mode Exit fullscreen mode

现在让我们编辑 App.js 文件,添加一个显示产品列表的简单 UI:



// /client/src/App.js

import React, { useState, useEffect } from "react";

// SERVICES
import productService from './services/productService';

function App() {
  const [products, setproducts] = useState(null);

  useEffect(() => {
    if(!products) {
      getProducts();
    }
  })

  const getProducts = async () => {
    let res = await productService.getAll();
    console.log(res);
    setproducts(res);
  }

  const renderProduct = product => {
    return (
      <li key={product._id} className="list__item product">
        <h3 className="product__name">{product.name}</h3>
        <p className="product__description">{product.description}</p>
      </li>
    );
  };

  return (
    <div className="App">
      <ul className="list">
        {(products && products.length > 0) ? (
          products.map(product => renderProduct(product))
        ) : (
          <p>No products found</p>
        )}
      </ul>
    </div>
  );
}

export default App;



Enter fullscreen mode Exit fullscreen mode

此时,您可以使用命令 npm run dev 再次运行该应用程序,您将看到以下屏幕:

使用PostmanInsomnia等 HTTP 客户端添加一些产品。向http://localhost:5000/api/product发出 POST 请求,内容如下:



{
  "name": "<product name>",
  "description": "<product description here>"
}


Enter fullscreen mode Exit fullscreen mode

现在,您将能够看到屏幕上呈现的产品列表,如下所示:

我希望您会发现本教程很有用,并且在接下来的几天里我将继续本教程,展示如何将这个应用程序 Docker 化。

另请查看下一篇文章,其中解释了如何将此应用程序部署到 heroku

如果您对使用容器感兴趣,我还发表了这篇文章,解释了如何将此应用程序 dockerize 并部署到 Heroku

源代码可以在这里找到

文章来源:https://dev.to/pacheco/my-fullstack-setup-node-js-react-js-and-mongodb-2a4k
PREV
什么是 BEM 以及为什么使用它来命名 HTML 类!
NEXT
为 Node.js API 设计更好的架构设置数据库创建控制器创建路由