Thứ năm, 12/12/2019 | 00:00 GMT+7

Cách bắt đầu với MERN Stack

Ngăn xếp MERN bao gồm MongoDB, Express, React / Redux và Node.js. Ngăn xếp MERN là một trong những ngăn xếp JavaScript phổ biến nhất để xây dựng các ứng dụng web một trang hiện đại.

Trong hướng dẫn này, bạn sẽ xây dựng một ứng dụng todo sử dụng API RESTful , bạn cũng sẽ xây dựng sau trong hướng dẫn này.

Yêu cầu

Để làm theo hướng dẫn này, bạn cần cài đặt node và npm trên máy tính của bạn . Nếu bạn chưa cài đặt nút, hãy làm theo hướng dẫn trên trang web nodejs. Bạn cũng cần một trình soạn thảo mã quen thuộc, tốt nhất là một trình soạn thảo có hỗ trợ tô sáng mã JavaScript.

Ảnh chụp màn hình động của một ứng dụng todo

Cài đặt mã ứng dụng

Hãy bắt đầu với cài đặt . Mở terminal của bạn và tạo một folder file mới ở bất kỳ vị trí thuận tiện nào trên máy local của bạn. Bạn có thể đặt tên cho nó bất cứ thứ gì nhưng trong ví dụ này, nó được gọi là Todo .

  • mkdir Todo

Bây giờ hãy nhập vào folder file đó

  • cd Todo

Bước tiếp theo là khởi tạo dự án bằng file package.json . Tệp này sẽ chứa một số thông tin về ứng dụng của ta và các phụ thuộc mà nó cần để chạy. Bạn có thể sử dụng npm init và làm theo hướng dẫn khi được yêu cầu , hoặc bạn có thể sử dụng npm init -y để sử dụng các giá trị mặc định.

Cài đặt server nút

Để chạy mã javascript của ta trên chương trình backend , ta cần quay một server sẽ biên dịch mã của ta . Server có thể được tạo theo hai cách: đầu tiên là sử dụng module http được tích hợp sẵn trong nút; thứ hai là sử dụng khung expressjs .

Hướng dẫn này sẽ sử dụng expressjs. Nó là một khung HTTP nodejs xử lý rất nhiều thứ và yêu cầu rất ít mã để tạo các API RESTful đầy đủ chức năng. Để sử dụng express, hãy cài đặt nó bằng npm:

  • npm install express

Bây giờ, hãy tạo một file index.js và nhập mã bên dưới vào nó và lưu:

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}`) }); 

Đoạn mã này được trích từ đoạn mã trên giúp xử lý các vấn đề liên quan đến CORS mà bạn có thể gặp phải khi cố gắng truy cập api từ các domain khác nhau trong quá trình phát triển và thử nghiệm:

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(); }); 

Đã đến lúc khởi động server của ta để xem nó có hoạt động không. Mở terminal của bạn trong cùng folder với file index.js của bạn và nhập:

  • node index.js

Nếu mọi thứ suôn sẻ, bạn sẽ thấy Server chạy trên cổng 5000 trong terminal của bạn .

Các tuyến đường

Có ba điều mà ứng dụng cần làm: tạo một tác vụ; xem tất cả các nhiệm vụ; và xóa một nhiệm vụ đã hoàn thành. Đối với mỗi tác vụ, ta cần tạo các tuyến sẽ xác định các điểm cuối khác nhau mà ứng dụng việc làm sẽ phụ thuộc vào. Vì vậy, hãy tạo một routes folder và tạo một file api.js với mã sau trong đó.

  • mkdir routes

Chỉnh sửa api.js và dán mã sau vào đó:

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; 

Mô hình

Bây giờ đến phần thú vị, vì ứng dụng sẽ sử dụng mongodb là database noSql, ta cần tạo một mô hình và một schemas . Mô hình được xác định bằng giao diện Lược đồ. Lược đồ cho phép bạn xác định các trường được lưu trữ trong mỗi tài liệu cùng với các yêu cầu xác thực và giá trị mặc định của chúng. Về bản chất, Lược đồ là một bản thiết kế database sẽ được xây dựng như thế nào. Ngoài ra, bạn có thể xác định các phương thức trợ giúp trường hợp và tĩnh để giúp làm việc với các kiểu dữ liệu dễ dàng hơn, cũng như các thuộc tính ảo mà bạn có thể sử dụng như bất kỳ trường nào khác, nhưng không thực sự được lưu trữ trong database .

Để tạo một Lược đồ và một mô hình, hãy cài đặt mongoose là một gói nút giúp làm việc với mongodb dễ dàng hơn.

  • npm install mongoose

Tạo một folder mới trong folder root của bạn và đặt tên cho nó là models . Bên trong nó tạo một file và đặt tên là todo.js với mã sau:

  • mkdir models

Dán phần sau vào todo.js bằng editor của bạn:

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; 

Bây giờ ta cần cập nhật các tuyến đường của bạn để sử dụng mô hình mới.

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

Ta cần một database nơi ta sẽ lưu trữ dữ liệu của bạn . Đối với điều này, ta sẽ sử dụng mlab. Theo dõi tài liệu này để bắt đầu với mlab. Sau khi cài đặt database , bạn cần cập nhật file index.js bằng mã sau:

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}`) }); 

Trong đoạn mã trên, ta đã sử dụng process.env để truy cập các biến môi trường cần được tạo. Tạo một file trong folder root của bạn với tên .env và chỉnh sửa:

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

Đảm bảo rằng bạn sử dụng URL mongodb của riêng mình từ mlab sau khi bạn tạo database và user của bạn . Thay thế <USER> bằng tên user và <PASSWORD> bằng password của user bạn đã tạo. Để làm việc với biến môi trường, ta phải cài đặt một gói nút có tên dotenv đảm bảo rằng ta có quyền truy cập vào biến môi trường được lưu trữ trong file .env .

  • npm install dotenv

Sau đó, yêu cầu và cấu hình nó trong index.js :

require('dotenv').config() 

Việc sử dụng các biến môi trường thay vì ghi trực tiếp thông tin đăng nhập vào mã ứng dụng có thể ẩn thông tin nhạy cảm khỏi hệ thống lập version của ta . Nó được coi là phương pháp hay nhất để tách cấu hình và dữ liệu bí mật khỏi mã ứng dụng theo cách này.

Kiểm tra Api

Đây là phần ta bắt đầu thử mọi thứ đảm bảo api RESTful của ta đang hoạt động. Vì giao diện user của ta chưa sẵn sàng, ta có thể sử dụng một số ứng dụng phát triển api để kiểm tra mã của ta . Bạn có thể sử dụng Người đưa thư hoặc Người mất ngủ hoặc nếu có một khách hàng khác mà bạn muốn thử nghiệm API, bạn có thể sử dụng nó.

Khởi động server của bạn bằng lệnh:

  • node index.js

Bây giờ hãy mở ứng dụng client của bạn, tạo một phương thức get và chuyển đến http: // localhost: 5000 / api / todos

Ảnh chụp màn hình của khách hàng Ins mất ngủ REST

Bạn nên kiểm tra tất cả các điểm cuối api và đảm bảo chúng đang hoạt động. Đối với các điểm cuối yêu cầu nội dung, bạn nên gửi lại json với các trường cần thiết vì đó là những gì ta cài đặt trong mã của bạn .

Tạo giao diện user

Vì ta đã hoàn thành chức năng ta muốn từ api của bạn , nên đã đến lúc tạo một giao diện để khách hàng tương tác với api. Để bắt đầu với giao diện user của ứng dụng todo, ta sẽ sử dụng lệnh create-react-app để xây dựng ứng dụng của bạn .

Trong cùng folder root với mã backend của bạn, đó là folder việc cần làm, hãy chạy:

  • create-react-app client

Điều này sẽ tạo ra một folder mới trong bạn todo folder gọi là client , nơi bạn sẽ thêm tất cả các phản ứng mã.

Chạy ứng dụng React

Trước khi thử nghiệm ứng dụng phản ứng, cần phải cài đặt một số phụ thuộc số od.

  1. Cài đặt đồng thời dưới dạng phụ thuộc nhà phát triển:
  • npm install concurrently --save-dev

Đồng thời được sử dụng để chạy nhiều hơn một lệnh đồng thời từ cùng một cửa sổ terminal .

  1. Cài đặt nodemon làm phụ thuộc nhà phát triển:
  • npm install nodemon --save-dev

Nodemon được sử dụng để chạy server và giám sát nó. Nếu có bất kỳ thay đổi nào trong mã server , nodemon sẽ tự động khởi động lại nó với những thay đổi mới.

  1. Mở file package.json của bạn trong folder root của dự án ứng dụng và dán mã sau
{ "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. Nhập vào folder khách hàng, sau đó tìm file package.json và thêm cặp giá trị khóa bên dưới vào bên trong nó. Cài đặt proxy này trong file package.json của ta sẽ cho phép ta thực hiện các cuộc gọi api mà không cần phải nhập url đầy đủ, chỉ cần / api / todos sẽ nhận được tất cả các việc cần làm của ta
"proxy": "http://localhost:5000" 

Mở terminal của bạn và chạy npm run dev và đảm bảo bạn đang ở trong folder việc làm chứ không phải trong folder client . Ứng dụng của bạn phải mở và chạy trên localhost: 3000 .

Tạo các thành phần React của bạn

Một trong những lợi thế của react là nó sử dụng các thành phần có thể tái sử dụng và cũng làm cho mã trở thành module . Đối với ứng dụng todo của ta , sẽ có hai thành phần trạng thái và một thành phần không trạng thái. Bên trong folder src của bạn, tạo một folder khác được gọi là components và bên trong nó tạo ba file Input.js , ListTodo.jsTodo.js

Mở file Input.js và dán nội dung sau

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 

Để sử dụng axios, một ứng dụng HTTP dựa trên Promise cho trình duyệt và node.js, bạn cần cd vào ứng dụng client của bạn từ terminal của bạn và chạy sợi add axios hoặc npm install axios

  • cd client
  • npm install axios

Sau đó, mở file ListTodo.js của bạn và dán mã sau

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 

Sau đó, trong file Todo.js của bạn, bạn viết mã sau

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; 

Ta cần điều chỉnh một chút đối với mã phản ứng của bạn . Xóa logo và điều chỉnh App.js của ta để trông giống như thế này.

import React from 'react';  import Todo from './components/Todo'; import './App.css';  const App = () => {   return (     <div className="App">       <Todo />     </div>   ); }  export default App; 

Sau đó, dán mã sau vào 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;   } } 

Cũng trong index.css thêm các luật sau:

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; } 

Giả sử không có lỗi khi lưu tất cả các file này, ứng dụng todo phải sẵn sàng và hoạt động đầy đủ với chức năng được thảo luận trước đó: tạo tác vụ, xóa tác vụ và xem tất cả tác vụ của bạn.

Kết luận

Trong hướng dẫn này, bạn đã tạo một ứng dụng todo bằng cách sử dụng ngăn xếp MERN. Bạn đã viết một ứng dụng giao diện user bằng React giao tiếp với ứng dụng backend được viết bằng expressjs. Bạn cũng đã tạo một chương trình backend Mongodb để lưu trữ các việc trong database .


Tags:

Các tin liên quan