前端时间把create-react-app脚手架搭建的react项目中的webpack版本从1.X更新到4.X,踩了不少坑,于是今天准备利用webpack 4.X从零搭建react聊天室( 去TM的脚手架,一辈子不更新,wdnmd )
已完成功能:
- 用户注册、登录
- 用户进入/离开聊天室,通知当前聊天室内所有用户
- 单个用户新增群聊,所有用户可以看到
- 用户可实时与所有人聊天
- 聊天室记录用户未读消息
- 点击用户头像,新增私聊
- 用户可实时单人私聊
- 用户离线保留聊天列表、聊天记录
- 用户正在输入功能
资源链接:https://github.com/zhangyongwnag/chat_room
文章目录
一、webpack配置React开发、生产环境
1、初始化下载
npm init
npm i webpack webpack-cli -D
2、配置目录

3、配置react环境
package.json 注入dev开发环境,build生产环境。查看完整配置
...
"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"
},
...
前篇文章我们具体配置了webpack,所以这里我们只配置loader对react的处理。查看完整配置
指定当前babel-loader版本进行下载,plugin-proposal-class-properties用来兼容箭头函数写法
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,第三方代码已经处理,不需要二次处理
}
}
},
...
这里我们单独配置babelrc
.babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-transform-runtime",
[
"@babel/plugin-proposal-class-properties",
{
"loose": false
}
]
]
}
到这里,我们就配置完成react的开发、生产环境,接下来,我们启动项目测试是否满足react开发环境
index.js入口文件
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.js主文件:
import React,{Component} from 'react'
export default class App extends Component {
constructor(){
super()
}
render() {
return (
<div>
简易聊天
</div>
)
}
}
webpack.config.js 热加载配置
...
// 热加载
devServer: {
host: '0.0.0.0', // host地址
port: '8080', // 端口
open: true, //自动拉起浏览器
hot: true, //热加载
hotOnly: true, // 热加载不更新
// proxy: {}, // 跨域
// bypass: {} // 拦截器
},
...
执行npm run dev启动热加载项目

我们可以看到控制台编译完成,接下来,我们打开http://localhost:8080可以看到,项目已经启动成功,并且热加载可以正常加载

二、编写静态聊天室页面
1、设计图
接下来,我们开始写页面,我们首先绘制一个大概的布局设计图

看着这个设计图,我们首先想到flex布局,左边聊天列表,右边聊天记录信息。
2、绘制PC布局
首先绘制一个包裹器,利用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); /* 标准的语法(必须放在最后) */
}
我们可以看到,一个渐变背景绘制完成,接下来,我们绘制主布局
因为后面很多逻辑代码,这里绘制布局过程就不在详解
布局主要是聊天记录比较麻烦,包括自己的消息,他人的消息,系统服务消息等
有需要的访问 [源码](https://github.com/zhangyongwnag/chat_room
PC端页面基本绘制完毕的效果:

3、响应式布局
接下来,我们加几个断点,做一个简单的响应式布局
@media screen and (max-width: 967px) {
...
}
@media screen and (max-width: 667px) {
...
}
@media screen and (max-width: 479px) {
...
}
效果:
①:max-width 967px:分辨率较小电脑

②:max-width 667px:iPad客户端

③:max-width 479px:手机客户端

布局暂时告以段落
三、启动mongodb数据库
1、安装环境
node:https://nodejs.org/zh-cn/download/mongodb:https://www.mongodb.com/try/download/communityNosql manager for mongodb:https://www.mongodbmanager.com/download
2、启动mongodb数据库
安装完成之后,我们在根目录下新建data文件夹用来存放数据:

接下来,我们进入bin目录,打开命令行窗口,执行:mongod --dbpath X:\mongdb\data,这里的路径是刚才建立data文件夹的路径

我们可以看到启动成功了,端口是27017,接下来,我们打开bin目录下的mongo.exe
这里可以利用命令行操作数据,基本的命令这里就不在演示了,我们新建一个new数据库,并且插入一条数据

3、连接数据库
接下来,我们利用可视化应用连接数据库

连接成功了,并且可以看到我们刚才利用命令行插入的一条数据

四、启动node服务器
1、下载
npm i mongoose express -D // mongoose封装的mongodb、expres中间件
npm i socket.io -S // 利用socket.io完成与客户端通信
2、初始化
根目录创建文件夹,server文件夹,包含index.js主文件,和module文件夹配置schame/model等
module文件夹下存放三个配置文件User.js Room.js Records.js,分别对应数据库的三张表users rooms records

这里我们连接chat数据库,并且启动socket服务端
-
这里总结以下几点:
-
1. 连接
mongodb数据库期间,建立schame/mode,会导致初始化失败,这里建立时使用require同步加载 -
2. 数据库使用唯一约束(unique)时,要加上
mongoose.set('useCreateIndex', true),否则控制台会警告 -
3. 数据库唯一约束的
_id是ObjectId类型,mongoose给我们提供了转次类型的方式:mongoose.Types.ObjectId -
4. 把
useNewUrlParser设置为true来避免“不建议使用当前URL字符串解析器”警告 -
5.
mongoose报错: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,设置useUnifiedTopology为true可以解决
server/index.js 主文件
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}`)
})
我们在package.json中添加一个命令用来启动服务器
package.json配置文件:
...
"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"
},
...
接下来,我们执行npm run server启动服务器

我们看到服务器启,访问http://127.0.0.1:3001/查看效果
3、设计schame模型
可以看到服务器成功启动了,接下来,我们设计数据库模型
module/User.js:users模型
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:rooms模型
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:records模型
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、测试model生成数据
接下来,我们插入一条测试数据:
...
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))
...
我们进入数据库查看结果,可以看到数据插入成功


本文详细介绍如何使用Webpack4.X、React、Node和Mongodb从零开始搭建一个具备用户注册、登录、实时聊天等功能的聊天室应用。文章涵盖前端、后端及数据库配置,适合希望深入了解全栈开发流程的技术人员。
202

被折叠的 条评论
为什么被折叠?



