当前位置: 首页 > 工具软件 > MERN > 使用案例 >

mern技术栈好处?_如何开始使用MERN堆栈

严曜文
2023-12-01

mern技术栈好处?

介绍 (Introduction)

The MERN stack consists of MongoDB, Express, React / Redux, and Node.js. The MERN stack is one of the most popular JavaScript stacks for building modern single-page web applications.

MERN堆栈由MongoDB,Express,React / Redux和Node.js组成。 MERN堆栈是用于构建现代单页Web应用程序的最受欢迎JavaScript堆栈之一。

In this tutorial, you will build a todo application that uses a RESTful API, which you will also build later in this tutorial.

在本教程中,您将构建一个使用RESTful API的todo应用程序 ,您还将在本教程的稍后部分中构建该应用程序

先决条件 (Prerequisites)

To follow along with this tutorial, you will need to install node and npm on your computer. If you do not have node installed, follow the instructions on the nodejs website. You will also need a code editor that you are familiar with, preferably one that has support for JavaScript code highlighting.

要遵循本教程,您将需要在计算机上安装node和npm。 如果尚未安装节点,请按照nodejs网站上的说明进行操作。 您还需要一个熟悉的代码编辑器,最好是一个支持JavaScript代码突出显示的代码编辑器。

应用程序代码设置 (Application Code Setup)

Let’s start with the setup. Open your terminal and create a new file directory in any convienient location on your local machine. You can name it anything but in this example it is called Todo.

让我们从设置开始。 打开终端,并在本地计算机上任何方便的位置创建一个新的文件目录。 您可以给它起任何名字,但在本示例中,它称为Todo

  • mkdir Todo

    麦克迪尔·托多

Now enter into that file directory

现在进入该文件目录

  • cd Todo

    cd待办事项

The next step is to initialize the project with a package.json file. This file will contain some information about our app and the dependencies that it needs to run. You can use npm init and follow the instructions when prompted, or you can use npm init -yto use the default values.

下一步是使用package.json文件初始化项目。 该文件将包含有关我们的应用程序以及它需要运行的依赖项的一些信息。 您可以使用npm init并按照提示进行操作,也可以使用npm init -y使用默认值。

节点服务器设置 (Node Server Setup)

To run our javascript code on the backend we need to spin up a server that will compile our code. The server can be created in two ways: first is to use the built in http module in node; second is to make use of the expressjs framework.

要在后端运行我们的javascript代码,我们需要启动一个服务器来编译我们的代码。 可以通过两种方式创建服务器:首先是在节点中使用内置的http模块。 其次是利用expressjs框架

This tutorial will use expressjs. It is a nodejs HTTP framework that handles a lot of things out of the box and requires very little code to create fully functional RESTful APIs. To use express, install it using npm:

本教程将使用expressjs。 它是一个nodejs HTTP框架,可以处理很多现成的事情,并且只需很少的代码即可创建功能齐全的RESTful API。 要使用express,请使用npm安装它:

  • npm install express

    npm安装快递

Now create a file index.js and type the code below into it and save:

现在创建一个文件index.js并在其中键入以下代码并保存:

const express = require('express');
require('dotenv').config();

const app = express();

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

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.use((req, res, next) => {
  res.send('Welcome to Express');
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`)
});

This snipped from the code above helps handle CORS related issues that you might face when trying to access the api from different domains during development and testing:

从上面的代码中摘录的代码有助于解决在开发和测试过程中尝试从不同域访问api时可能遇到的CORS相关问题:

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

It’s time to start our server to see if it works. Open your terminal in the same directory as your index.js file and type:

现在是时候启动我们的服务器以查看其是否正常工作了。 在与index.js文件相同的目录中打开终端,然后键入:

  • node index.js

    节点index.js

If every thing goes well, you should see Server running on port 5000 in your terminal.

如果一切顺利,您应该在终端中看到服务器在端口5000上运行

路线 (Routes)

There are three things that the app needs to do: create a task; view all tasks; and delete a completed task. For each task, we need to create routes that will define various endpoints that the todo app will depend on. So let’s create a folder routes and create a file api.js with the following code in it.

应用程序需要做三件事:创建任务; 查看所有任务; 并删除已完成的任务。 对于每个任务,我们需要创建路由来定义待办事项应用程序依赖的各种端点。 因此,让我们创建一个文件夹routes并使用以下代码创建一个文件api.js

  • mkdir routes

    mkdir路线

Edit api.js and paste the following code in it:

编辑api.js并在其中粘贴以下代码:

const express = require ('express');
const router = express.Router();

router.get('/todos', (req, res, next) => {

});

router.post('/todos', (req, res, next) => {

});

router.delete('/todos/:id', (req, res, next) => {

})

module.exports = router;

楷模 (Models)

Now comes the interesting part, since the app is going to make use of mongodb which is a noSql database, we need to create a model and a schema. Models are defined using the Schema interface. The Schema allows you to define the fields stored in each document along with their validation requirements and default values. In essence the Schema is a blueprint of how the database will be constructed. In addition, you can define static and instance helper methods to make it easier to work with your data types, and also virtual properties that you can use like any other field, but which aren’t actually stored in the database.

现在介绍有趣的部分,因为该应用程序将使用mongodb(这是一个noSql数据库),因此我们需要创建一个模型和一个架构。 使用Schema接口定义模型。 通过该架构,您可以定义每个文档中存储的字段以及它们的验证要求和默认值。 从本质上讲,该架构是如何构建数据库的蓝图。 另外,您可以定义静态和实例帮助器方法以使您更轻松地使用数据类型,以及可以像其他任何字段一样使用但实际上未存储在数据库中的虚拟属性。

To create a Schema and a model, install mongoose which is a node package that makes working with mongodb easier.

要创建模式和模型,请安装mongoose ,这是一个使mongodb易于使用的节点程序包。

  • npm install mongoose

    npm安装猫鼬

Create a new folder in your root directory and name it models. Inside it create a file and name it todo.js with the following code in it:

在您的根目录中创建一个新文件夹,并将其命名为models 。 在其中创建一个文件,并使用以下代码将其命名为todo.js

  • mkdir models

    mkdir模型

Paste the following into todo.js with your text editor:

使用您的文本编辑器将以下内容粘贴到todo.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

//create schema for todo
const TodoSchema = new Schema({
  action: {
    type: String,
    required: [true, 'The todo text field is required']
  }
})

//create model for todo
const Todo = mongoose.model('todo', TodoSchema);

module.exports = Todo;

Now we need to update our routes to make use of the new model.

现在,我们需要更新路线以使用新模型。

const express = require ('express');
const router = express.Router();
const Todo = require('../models/todo');

router.get('/todos', (req, res, next) => {

  //this will return all the data, exposing only the id and action field to the client
  Todo.find({}, 'action')
    .then(data => res.json(data))
    .catch(next)
});

router.post('/todos', (req, res, next) => {
  if(req.body.action){
    Todo.create(req.body)
      .then(data => res.json(data))
      .catch(next)
  }else {
    res.json({
      error: "The input field is empty"
    })
  }
});

router.delete('/todos/:id', (req, res, next) => {
  Todo.findOneAndDelete({"_id": req.params.id})
    .then(data => res.json(data))
    .catch(next)
})

module.exports = router;

数据库 (Database)

We need a database where we will store our data. For this we will make use of mlab. Follow this doc to get started with mlab. After setting up your database you need to update index.js file with the following code:

我们需要一个数据库来存储数据。 为此,我们将使用mlab。 按照此文档开始使用mlab。 设置数据库后,您需要使用以下代码更新index.js文件:

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

const app = express();

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

//connect to the database
mongoose.connect(process.env.DB, { useNewUrlParser: true })
  .then(() => console.log(`Database connected successfully`))
  .catch(err => console.log(err));

//since mongoose promise is depreciated, we overide it with node's promise
mongoose.Promise = global.Promise;

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.use(bodyParser.json());

app.use('/api', routes);

app.use((err, req, res, next) => {
  console.log(err);
  next();
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`)
});

In the code above we made use of process.env to access environment variables, which need to be created. Create a file in your root directory with name .env and edit:

在上面的代码中,我们使用了process.env来访问需要创建的环境变量。 在根目录中创建一个名为.env的文件,然后编辑:

DB = ‘mongodb://<USER\>:<PASSWORD\>@ds039950.mlab.com:39950/todo’

DB ='mongodb:// <USER \>:<PASSWORD \> @ ds039950.mlab.com:39950 / todo'

Make sure you use your own mongodb URL from mlab after you created your database and user. Replace <USER> with the username and <PASSWORD> with the password of the user you created. To work with environment variable we have to install a node package called dotenv that makes sure we have access to environment variable stored in the .env file.

创建数据库和用户后,请确保使用来自mlab的自己的mongodb URL。 将<USER>替换为用户名,并将<PASSWORD>替换为您创建的用户的密码。 要使用环境变量,我们必须安装名为dotenv的节点包,以确保我们可以访问存储在.env文件中的环境变量。

  • npm install dotenv

    npm安装dotenv

Then require and configure it in index.js:

然后要求并在index.js配置它:

require('dotenv').config()

Using environment variables instead of writing credentials to the application code directly can hide sensitive information from our versioning system. It is considered a best practice to separate configuration and secret data from application code in this manner.

使用环境变量而不是直接将凭据写入应用程序代码可以从我们的版本控制系统中隐藏敏感信息。 以这种方式从应用程序代码中分离配置和机密数据被认为是最佳实践。

测试Api (Testing Api)

This is the part we start trying out things to make sure our RESTful api is working. Since our frontend is not ready yet, we can make use of some api development clients to test our code. You can use of Postman or Insomnia or if there is another client that you prefer for testing APIs, you can use of it.

这是我们开始尝试确保RESTful api正常工作的部分。 由于我们的前端尚未准备好,我们可以利用一些api开发客户端来测试我们的代码。 您可以使用PostmanInsomnia ,也可以使用其他客户端来测试API。

Start your server using the command:

使用以下命令启动服务器:

  • node index.js

    节点index.js

Now open your client, create a get method and navigate to http://localhost:5000/api/todos

现在打开您的客户端,创建一个get方法并导航到http:// localhost:5000 / api / todos

You should test all the api endpoints and make sure they are working. For the endpoints that require body, you should send json back with the necessary fields since it’s what we setup in our code.

您应该测试所有api端点,并确保它们正常工作。 对于需要正文的端点,您应该将json与必要的字段一起发送回去,因为这是我们在代码中设置的。

创建前端 (Creating the Frontend)

Since we are done with the functionality we want from our api, it is time to create an interface for the client to interact with the api. To start out with the frontend of the todo app, we will use the create-react-app command to scaffold our app.

由于我们已经完成了api所需的功能,因此现在该为客户端创建一个与api进行交互的接口了。 首先从todo应用程序的前端开始,我们将使用create-react-app命令来搭建我们的应用程序。

In the same root directory as your backend code, which is the todo directory, run:

在与后端代码相同的根目录(即todo目录)中,运行:

  • create-react-app client

    创建React应用程序客户端

This will create a new folder in your todo directory called client, where you will add all the react code.

这将在todo目录中创建一个名为client的新文件夹,您将在其中添加所有React代码。

运行React应用 (Running the React App)

Before testing the react app, there are a number od dependencies that need to be installed.

在测试React应用之前,需要安装一些od依赖项。

  1. Install concurrently as a dev dependency:

    作为开发依赖项并发安装:

  • npm install concurrently --save-dev

    npm同时安装--save-dev

Concurrently is used to run more than one command simultaneously from the same terminal window.

同时用于从同一终端窗口同时运行多个命令。

  1. Install nodemon as a dev dependency:

    安装nodemon作为dev依赖项:

  • npm install nodemon --save-dev

    npm install nodemon --save-dev

Nodemon is used to run the server and monitor it as well. If there is any change in the server code, nodemon will restart it automatically with the new changes.

Nodemon用于运行服务器并对其进行监视。 如果服务器代码有任何更改,nodemon将使用新更改自动重新启动它。

  1. Open your package.json file in the root folder of the app project, and paste the following code

    在应用程序项目的根文件夹中打开package.json文件,然后粘贴以下代码
{
"name": "todo",
"version": "1.0.0",
"description": "building todo app using mongodb, express, react and nodejs",
"main": "index.js",
"scripts": {
"start": "node index.js",
"start-watch": "nodemon index.js",
"dev": "concurrently \"yarn run start-watch\" \"cd client && yarn start\""
},
"author": "Ojini Jude",
"license": "MIT",
"dependencies": {
"body-parser": "^1.18.3",
"dotenv": "^6.1.0",
"express": "^4.16.4",
"mongoose": "^5.3.6"
},
"devDependencies": {
"concurrently": "^4.0.1",
"nodemon": "^1.18.4"
}
}
  1. Enter into the client folder, then locate the package.json file and add the key value pair below inside it. This proxy setup in our package.json file will enable us make api calls without having to type the full url, just /api/todos will get all our todos

    输入到客户端文件夹,然后找到package.json文件,并在其下面添加键值对。 package.json文件中的此代理设置将使我们能够进行api调用,而无需键入完整的url,仅/ api / todos即可获取所有待办事项
"proxy": "http://localhost:5000"

Open your terminal and run npm run dev and make sure you are in the todo directory and not in the client directory. Your app should be open and running on localhost:3000.

打开终端并运行npm run dev ,并确保您位于todo目录中,而不在client目录中。 您的应用应已打开并在localhost:3000上运行。

创建您的React组件 (Creating your React Components)

One of the advantages of react is that it makes use of components, which are reusable and also makes code modular. For our todo app, there will be two state components and one stateless component. Inside your src folder create another folder called components and inside it create three files Input.js, ListTodo.js and Todo.js.

react的优点之一是它利用了可重用的组件,并使代码模块化。 对于我们的待办事项应用程序,将有两个状态组件和一个无状态组件。 在src文件夹中,创建另一个名为components文件夹,并在其中创建三个文件Input.jsListTodo.jsTodo.js

Open Input.js file and paste the following

打开Input.js文件并粘贴以下内容

import React, { Component } from 'react';
import axios from 'axios';


class Input extends Component {

  state = {
    action: ""
  }

  addTodo = () => {
    const task = {action: this.state.action}

    if(task.action && task.action.length > 0){
      axios.post('/api/todos', task)
        .then(res => {
          if(res.data){
            this.props.getTodos();
            this.setState({action: ""})
          }
        })
        .catch(err => console.log(err))
    }else {
      console.log('input field required')
    }
  }

  handleChange = (e) => {
    this.setState({
      action: e.target.value
    })
  }

  render() {
    let { action } = this.state;
    return (
      <div>
        <input type="text" onChange={this.handleChange} value={action} />
        <button onClick={this.addTodo}>add todo</button>
      </div>
    )
  }
}

export default Input

To make use of axios, which is a Promise based HTTP client for the browser and node.js, you need to cd into your client from your terminal and run yarn add axios or npm install axios

要使用axios,这是浏览器和node.js的基于Promise的HTTP客户端,您需要从终端cd进入客户端,然后运行yarn add axios或npm install axios

  • cd client

    cd客户端
  • npm install axios

    npm安装axios

After that open your ListTodo.js file and paste the following code

之后,打开您的ListTodo.js文件并粘贴以下代码

import React from 'react';

const ListTodo = ({ todos, deleteTodo }) => {

  return (
    <ul>
      {
        todos &&
          todos.length > 0 ?
            (
              todos.map(todo => {
                return (
                  <li key={todo._id} onClick={() => deleteTodo(todo._id)}>{todo.action}</li>
                )
              })
            )
            :
            (
              <li>No todo(s) left</li>
            )
      }
    </ul>
  )
}

export default ListTodo

Then in your Todo.js file you write the following code

然后在您的Todo.js文件中编写以下代码

import React, {Component} from 'react';
import axios from 'axios';

import Input from './Input';
import ListTodo from './ListTodo';

class Todo extends Component {

  state = {
    todos: []
  }

  componentDidMount(){
    this.getTodos();
  }

  getTodos = () => {
    axios.get('/api/todos')
      .then(res => {
        if(res.data){
          this.setState({
            todos: res.data
          })
        }
      })
      .catch(err => console.log(err))
  }

  deleteTodo = (id) => {

    axios.delete(`/api/todos/${id}`)
      .then(res => {
        if(res.data){
          this.getTodos()
        }
      })
      .catch(err => console.log(err))
  }

  render() {
    let { todos } = this.state;

    return(
      <div>
        <h1>My Todo(s)</h1>
        <Input getTodos={this.getTodos}/>
        <ListTodo todos={todos} deleteTodo={this.deleteTodo}/>
      </div>
    )
  }
}

export default Todo;

We need to make little adjustment to our react code. Delete the logo and adjust our App.js to look like this.

我们需要对React代码进行很少的调整。 删除徽标并调整我们的App.js使其如下所示。

import React from 'react';

import Todo from './components/Todo';
import './App.css';

const App = () => {
  return (
    <div className="App">
      <Todo />
    </div>
  );
}

export default App;

Then paste the following code into App.css:

然后将以下代码粘贴到App.css

.App {
  text-align: center;
  font-size: calc(10px + 2vmin);
  width: 60%;
  margin-left: auto;
  margin-right: auto;
}

input {
  height: 40px;
  width: 50%;
  border: none;
  border-bottom: 2px #101113 solid;
  background: none;
  font-size: 1.5rem;
  color: #787a80;
}

input:focus {
  outline: none;
}

button {
  width: 25%;
  height: 45px;
  border: none;
  margin-left: 10px;
  font-size: 25px;
  background: #101113;
  border-radius: 5px;
  color: #787a80;
  cursor: pointer;
}

button:focus {
  outline: none;
}

ul {
  list-style: none;
  text-align: left;
  padding: 15px;
  background: #171a1f;
  border-radius: 5px;
}

li {
  padding: 15px;
  font-size: 1.5rem;
  margin-bottom: 15px;
  background: #282c34;
  border-radius: 5px;
  overflow-wrap: break-word;
  cursor: pointer;
}

@media only screen and (min-width: 300px) {
  .App {
    width: 80%;
  }

  input {
    width: 100%
  }

  button {
    width: 100%;
    margin-top: 15px;
    margin-left: 0;
  }
}

@media only screen and (min-width: 640px) {
  .App {
    width: 60%;
  }

  input {
    width: 50%;
  }

  button {
    width: 30%;
    margin-left: 10px;
    margin-top: 0;
  }
}

Also in index.css add the following rules:

同样在index.css添加以下规则:

body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
    "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  box-sizing: border-box;
  background-color: #282c34;
  color: #787a80;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
    monospace;
}

Assuming no errors when saving all these files, the todo app should be ready and fully functional with the functionality discussed earlier: creating a task, deleting a task and viewing all your tasks.

假设保存所有这些文件时都没有错误,那么todo应用程序应该已经准备就绪并且可以使用前面讨论的功能完全正常运行:创建任务,删除任务并查看所有任务。

结论 (Conclusion)

In this tutorial, you created a todo app using the MERN stack. You wrote a frontend application using React that communicates with a backend application written using expressjs. You also created a Mongodb backend for storing tasks in a database.

在本教程中,您使用MERN堆栈创建了一个todo应用程序。 您使用React编写了一个前端应用程序,该前端应用程序与使用expressjs编写的后端应用程序进行通信。 您还创建了一个Mongodb后端,用于将任务存储在数据库中。

翻译自: https://www.digitalocean.com/community/tutorials/getting-started-with-the-mern-stack

mern技术栈好处?

 类似资料: