フロントエンドの時間中に、create-react-app
スキャフォールディングされたreact
プロジェクトのバージョンを 0webpack
から10 に1.X
更新し4.X
、多くの落とし穴に遭遇しました。そこで、今日はそれを使用してチャット ルームをwebpack 4.X
一から構築します (TM のスキャフォールディングにアクセスしてください。私の人生では更新されません、wdnmd)react
完成した機能:
- ユーザー登録、ログイン
- ユーザーがチャット ルームに出入りすると、現在のチャット ルームにいるすべてのユーザーに通知されます。
- 1 人のユーザーがグループ チャットを追加すると、すべてのユーザーがそれを見ることができます。
- ユーザーは誰とでもリアルタイムでチャットできます
- チャット ルームはユーザーからの未読メッセージを記録します
- ユーザーのアバターをクリックしてプライベート チャットを追加します
- ユーザーはリアルタイムでお互いにプライベートにチャットできます
- ユーザーはチャット リストとチャット記録をオフラインで保存できます
- ユーザーが関数を入力中です
リソースリンク: https://github.com/zhangyongwnag/chat_room
記事ディレクトリ
1. Webpack は React の開発および運用環境を構成します
1. 初回ダウンロード
npm init
npm i webpack webpack-cli -D
2. 設定ディレクトリ
3. 反応環境を構成する
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
プロジェクトが正常に起動され、ホットリロードが正常にロードできることがわかります。
2. 静的なチャット ルーム ページを作成する
1.設計図
次にページを書き始めます まず大まかなレイアウトデザインを描きます
このデザインを見て、まず左側にチャットリスト、右側にチャット記録情報を配置するフレックスレイアウトを考えます。
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: モバイルクライアント
レイアウトは一時的に終了しています
3. 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
フォルダーを作成します: 次に、ディレクトリに
入り、コマンド ライン ウィンドウを開いて、次のコマンドを実行します。ここでのパスは、作成したばかりのフォルダーへのパスです。起動が成功したことがわかります。ポートは 27017 です。次に、bin ディレクトリにある mongo.exe を開きますbin
mongod --dbpath X:\mongdb\data
data
ここではコマンド ラインを使用してデータを操作できます。基本的なコマンドはここでは説明しません。新しいnew
データベースを作成し、データを挿入します。
3. データベースに接続します
次に、ビジュアル アプリケーションを使用してデータベースに接続します。
接続は成功し、コマンド ラインを使用して挿入したばかりのデータが表示されます。
4. ノードサーバーを起動します
1. ダウンロード
npm i mongoose Express -D // Mongoose でカプセル化された mongodb、エクスプレス ミドルウェア
npm iソケット.io -S // クライアントとの通信を完了するためにソケット.io を使用します
2. 初期化
ルートディレクトリにフォルダー、メインファイルserver
を含むフォルダーindex.js
、module
フォルダー構成schame/model
などを作成します。
module
フォルダーには、User.js Room.js Records.js
データベースの 3 つのテーブルに対応する 3 つの構成ファイルが保存されています。ここで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. 設計スキームモデル
サーバーが正常に起動したことがわかります。次に、データベース モデルを設計します。
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. テストモデルがデータを生成する
次に、テスト データを挿入します。
...
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))
...
データベースに入って結果を表示すると、データが正常に挿入されたことがわかります。