Webpack 4.X + React + Node + Mongodb crea una sala de chat desde cero (1)

Durante el tiempo de front-end, actualicé la versión del proyecto create-react-appcon scaffolding de 0 a 10 y encontré muchos problemas, por lo que hoy voy a usarlo para construir una sala de chat desde cero (vaya al scaffolding de TM, no se actualizará en mi vida, wdnmd)reactwebpack1.X4.Xwebpack 4.Xreact

Funciones completadas:

  • Registro de usuario, inicio de sesión
  • Cuando el usuario entra o sale de la sala de chat, se notifica a todos los usuarios de la sala de chat actual.
  • Cuando un solo usuario agrega un chat grupal, todos los usuarios pueden verlo.
  • Los usuarios pueden chatear con cualquier persona en tiempo real.
  • Las salas de chat registran mensajes no leídos de los usuarios
  • Haga clic en el avatar del usuario para agregar un chat privado
  • Los usuarios pueden chatear de forma privada entre ellos en tiempo real.
  • Los usuarios pueden mantener listas de chat y registros de chat sin conexión
  • El usuario está ingresando a la función.

Enlace de recursos : https://github.com/zhangyongwnag/chat_room


1. Webpack configura el entorno de desarrollo y producción de React

1. Descarga inicial

npm init
npm i paquete web paquete web-cli -D

2. Directorio de configuración

Insertar descripción de la imagen aquí

3. Configurar el entorno de reacción.

package.jsonInyectar en devel entorno de desarrollo y builden el entorno de producción. Ver configuración completa

...
"scripts": {
    
    
  "dev": "cross-env NODE_TYPE=development webpack-dev-server --progress --colors --config webpack.config.js --mode=development",
  "build": "cross-env NODE_TYPE=production webpack -p --progress --colors --config webpack.config.js --mode=production"
},
...

Lo configuramos específicamente en el artículo anterior webpack, por lo que aquí solo configuramos loaderel reactprocesamiento correcto. Ver configuración completa


Especifique la versión actual babel-loaderpara descargar plugin-proposal-class-propertiespara que sea compatible con la escritura de la función de flecha.

npm i @babel/plugin-proposal-class-properties @babel/preset-react -D

webpack.config.js

...
{
    
    
  test: /\.(js|jsx)$/,
  use: {
    
    
    loader: 'babel-loader',
    options: {
    
    
      include: path.join(__dirname, 'src'),
      exclude: '/node_modules/', // 排除node_modules,第三方代码已经处理,不需要二次处理
    }
  }
},
...

Aquí lo configuramos por separado.babelrc

.babelrc

{
    
    
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-transform-runtime",
    [
      "@babel/plugin-proposal-class-properties",
      {
    
    
        "loose": false
      }
    ]
  ]
}

En este punto, hemos configurado los reactentornos de desarrollo y producción completos y luego iniciamos el proyecto para probar si cumple con reactel entorno de desarrollo.

index.jsArchivo de entrada

import React from 'react'
import ReactDOM from 'react-dom'
import App from './pages/App'

ReactDOM.render(<App/>,document.getElementById('app'))

if (module.hot){
    
    
  module.hot.accept(() => {
    
    

  })
}

app.jsArchivo principal:

import React,{
    
    Component} from 'react'

export default class App extends Component {
    
    
  constructor(){
    
    
    super()
  }
  render() {
    
    
    return (
      <div>
        简易聊天
      </div>
    )
  }
}

webpack.config.jsConfiguración de carga en caliente

...
  // 热加载
  devServer: {
    host: '0.0.0.0', // host地址
    port: '8080', // 端口
    open: true, //自动拉起浏览器
    hot: true, //热加载
    hotOnly: true, // 热加载不更新
    // proxy: {}, // 跨域
    // bypass: {} // 拦截器
  },
...

Cuando ejecutamos npm run devel proyecto de recarga en caliente de inicio
Insertar descripción de la imagen aquí
, podemos ver que la compilación de la consola está completa, luego, cuando la abrimos, podemos http://localhost:8080ver que el proyecto se inició con éxito y la recarga en caliente se puede cargar normalmente.
Proyecto cargado exitosamente

2. Escribe una página de sala de chat estática.

1. Dibujo de diseño

A continuación, comenzamos a escribir la página. Primero dibujamos un diseño aproximado
Insertar descripción de la imagen aquí
. Al observar este diseño, primero pensamos en un diseño flexible, con la lista de chat a la izquierda y la información del registro de chat a la derecha.

2. Dibujar el diseño de la PC

Primero dibuje un contenedor y use un degradado de fondo CSS

section {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: -webkit-linear-gradient(left top, #67c8b7, #3577cd); /* Safari 5.1 - 6.0 */
  background: -o-linear-gradient(bottom right, #67c8b7, #3577cd); /* Opera 11.1 - 12.0 */
  background: -moz-linear-gradient(bottom right, #67c8b7, #3577cd); /* Firefox 3.6 - 15 */
  background: linear-gradient(to bottom right, #67c8b7, #3577cd); /* 标准的语法(必须放在最后) */ 
}

Podemos ver que se dibuja un fondo degradado. A continuación, dibujamos el diseño principal.Insertar descripción de la imagen aquí Debido a que hay mucho código lógico detrás, el proceso de dibujo del diseño no se explicará en detalle aquí.

El diseño es principalmente problemático debido a los registros del chat, incluidos sus propios mensajes, los mensajes de otras personas, los mensajes de servicio del sistema, etc.

Si es necesario, visite [código fuente](https://github.com/zhangyongwnag/chat_room


El efecto de la página de la PC básicamente dibujada:
Insertar descripción de la imagen aquí

3. Diseño responsivo

A continuación, agregamos algunos puntos de interrupción y creamos un diseño responsivo simple.

@media screen and (max-width: 967px) {
	...
}

@media screen and (max-width: 667px) {
	...
}

@media screen and (max-width: 479px) {
	...
}

Efecto:

①: max-width967px: Computadora con resolución más pequeña
Insertar descripción de la imagen aquí
②: max-width667px: Cliente iPad
Insertar descripción de la imagen aquí
③: max-width479px: Cliente móvil
Insertar descripción de la imagen aquí
El diseño finalizó temporalmente

3. Inicie la base de datos mongodb

1. Entorno de instalación
2. Inicie la base de datos mongodb

dataUna vez completada la instalación, creamos una nueva carpeta en el directorio raíz para almacenar datos:
Insertar descripción de la imagen aquí
A continuación, ingresamos binal directorio, abrimos la ventana de línea de comando y ejecutamos:, mongod --dbpath X:\mongdb\datala ruta aquí es datala ruta a la carpeta que acabamos de crear
Insertar descripción de la imagen aquí
. Puede ver que el inicio fue exitoso, el puerto es 27017. A continuación, abrimos mongo.exe en el directorio bin.

Aquí puede usar la línea de comando para operar datos. Los comandos básicos no se muestran aquí. Creamos una nueva newbase de datos e insertamos un dato.
Insertar descripción de la imagen aquí

3. Conéctese a la base de datos

A continuación, usamos la aplicación visual para conectarnos a la base de datos, la
Insertar descripción de la imagen aquí
conexión es exitosa y podemos ver el dato que acabamos de insertar usando la línea de comando.
Insertar descripción de la imagen aquí

4. Inicie el servidor de nodo

1. Descargar

npm i mongoose express -D // Mongodb encapsulado por Mongoose, middleware express
npm i socket.io -S // Utilice socket.io para completar la comunicación con el cliente

2. Inicialización

Cree carpetas en el directorio raíz, servercarpetas que contengan index.jsarchivos principales y moduleconfiguraciones de carpetas schame/model, etc.

moduleHay tres archivos de configuración almacenados en la carpeta User.js Room.js Records.js, correspondientes a las tres tablas de la base de datos, users rooms records
Insertar descripción de la imagen aquí
aquí nos conectamos a chatla base de datos e iniciamos socketel servidor.

Aquí están los siguientes puntos:

1. mongodbDurante la conexión a la base de datos, el establecimiento schame/modeprovocará una falla de inicialización. Aquí se utiliza requirela carga sincrónica al establecerse.

2. Cuando la base de datos usa restricciones únicas (únicas), se debe agregar mongoose.set('useCreateIndex', true), de lo contrario la consola advertirá

3. La única restricción de la base de datos _ides ObjectIdel tipo, mongooselo que nos proporciona una forma de transferir el tipo:mongoose.Types.ObjectId

4. useNewUrlParserConfigúrelo en truepara evitar la advertencia "El uso del URLanalizador de cadenas actual está obsoleto".

5. mongooseInforme de error: DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor, configurado useUnifiedTopologypara truepoder solucionar

server/index.jsarchivo maestro

let express = require('express')
let app = express() // express中间件
let http = require('http').Server(app) // 建立http通信
let io = require('socket.io')(http) // 创建socket服务端
let path = require('path') // 路径操作
let chalk = require('chalk') // 控制控制台颜色
let fs = require('fs') // fs操作文件系统
let mongoose = require('mongoose') // mongoose中间件
let db = 'chat' // 连接的数据库名称
let ObjectId = mongoose.Types.ObjectId // 用来处理数据库唯一约束_id为ObjectId

// 设置数据库可使用唯一约束
mongoose.set('useCreateIndex', true)
// 连接数据库
mongoose.connect(`mongodb://127.0.0.1:27017/${
      
      db}`, {
    
    useNewUrlParser: true, useUnifiedTopology: true}, err => {
    
    
  console.log()
  if (err) {
    
    
    console.log(chalk.bgCyan(chalk.black(' S ')) + chalk.red(' Connect') + chalk.blue(` db.${
      
      db}`) + chalk.red(' failure'))
  } else {
    
    
    console.log(chalk.bgCyan(chalk.black(' S ')) + chalk.green(' Connect') + chalk.blue(` db.${
      
      db}`) + chalk.green(' successfully'))
  }
})

let User = require('./module/User')
let Room = require('./module/Room')
let Records = require('./module/Records')

app.get('/', (req, res) => {
    
    
  res.send('hello')
})

io.on('connection', socket => {
    
    })

/**
 * @description 启动服务器,因为绑定了socket.io服务端,这里要监听http服务,请勿express服务代替监听
 */
let server = http.listen(3001, '127.0.0.1', () => {
    
    
  let host = server.address().address
  let port = server.address().port

  console.log()
  console.log(chalk.bgGreen(chalk.black(' DONE ')) + chalk.green(` Compiled successfully at `) + chalk.blue(`${
      
      new Date().toLocaleString()}`))
  console.log()
  console.log(chalk.bgBlue(chalk.black(' I ')) + ` Server running at : http://${
      
      host}:${
      
      port}`)
})

Agregamos package.jsonun comando para iniciar el servidor.

package.jsonArchivo de configuración:

...
  "scripts": {
    "dev": "cross-env NODE_TYPE=development webpack-dev-server --progress --colors --config webpack.config.js --mode=development",
    "build": "cross-env NODE_TYPE=production webpack -p --progress --colors --config webpack.config.js --mode=production",
    "server": "node server/index.js"
  },
...

A continuación ejecutamos npm run serverel servidor de inicio,
Insertar descripción de la imagen aquí
vemos que el servidor se inicia, visita http://127.0.0.1:3001/para ver el efecto.Insertar descripción de la imagen aquí

3. Modelo de esquema de diseño

Puede ver que el servidor se inició correctamente, a continuación, diseñamos el modelo de base de datos.

module/User.js: usersModelo

let mongoose = require('mongoose')

// 创建 Schema
let UserSchema = mongoose.Schema({
    
    
  // 用户名称,唯一约束
  user_name: {
    
    
    type: String,
    unique: true,
    required: true
  },
  current_room_id: String, // 用户所处聊天室ID
  socket_id: String // 用户的socketID
}, {
    
    
  timestamps: {
    
    
    createdAt: 'createTime',
    updatedAt: 'updateTime'
  }
})

// 创建 User model
let User = mongoose.model('User', UserSchema)

module.exports = User

module/Room.js: roomsModelo

let mongoose = require('mongoose')

// 创建 Schema
let RoomSchema = mongoose.Schema({
    
    
  user_id: String, // 用户ID
  user_name: String, // 用户名称
  room_name: String, // 聊天室名称
  status: Number, // 0为群聊,其他为私聊
  num: Number, // 聊天是在线人数
  badge_number: Number, // 消息未读数
  current_status: Boolean // 当前用户是否处在当前聊天室
}, {
    
    
  timestamps: {
    
    
    createdAt: 'createTime',
    updatedAt: 'updateTime'
  }
})

// 创建 Room model
let Room = mongoose.model('Room', RoomSchema)

module.exports = Room

module/Records.js: recordsModelo

let mongoose = require('mongoose')

// 创建 Schema
let RecordSchema = mongoose.Schema({
  user_id: String, // 用户ID
  user_name: String, // 用户名称
  room_name: String, // 聊天室名称
  chat_content: String, // 聊天内容
  status: Number // 是否为系统服务消息
}, {
  timestamps: {
    createdAt: 'createTime',
    updatedAt: 'updateTime'
  }
})

// 创建 Room model
let Records = mongoose.model('Records', RecordSchema)

module.exports = Records
4. El modelo de prueba genera datos.

A continuación, insertamos un dato de prueba:

...
let User = require('./module/User')

let user = new User({
  user_name: '测试',
  current_room_id: '',
  socket_id: ''
})
// 注册用户插入数据库
user.save()
  .then(res => console.log('插入用户成功'))
  .catch(err => console.log('插入用户失败:' + err))
...

Ingresamos a la base de datos para ver los resultados y podemos ver que los datos se insertaron exitosamente.
Insertar descripción de la imagen aquí

5. Artículos relacionados

Supongo que te gusta

Origin blog.csdn.net/Vue2018/article/details/107428772
Recomendado
Clasificación