Webpack 4.X + React + Node + Mongodb でチャット ルームをゼロから構築する (1)

フロントエンドの時間中に、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.jsondev開発環境と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-width967px: 解像度の低いコンピュータ
ここに画像の説明を挿入します
②: max-width667px: iPad クライアント
ここに画像の説明を挿入します
③: max-width479px: モバイルクライアント
ここに画像の説明を挿入します
レイアウトは一時的に終了しています

3. mongodb データベースを起動します

1. 設置環境
2.mongodbデータベースを起動します

インストールが完了したら、データを保存するためにルート ディレクトリに新しいdataフォルダーを作成します: 次に、ディレクトリに
ここに画像の説明を挿入します
入り、コマンド ライン ウィンドウを開いて、次のコマンドを実行します。ここでのパスは、作成したばかりのフォルダーへのパスです。起動が成功したことがわかります。ポートは 27017 です。次に、bin ディレクトリにある mongo.exe を開きますbinmongod --dbpath X:\mongdb\datadata
ここに画像の説明を挿入します

ここではコマンド ラインを使用してデータを操作できます。基本的なコマンドはここでは説明しません。新しいnewデータベースを作成し、データを挿入します。
ここに画像の説明を挿入します

3. データベースに接続します

次に、ビジュアル アプリケーションを使用してデータベースに接続します。
ここに画像の説明を挿入します
接続は成功し、コマンド ラインを使用して挿入したばかりのデータが表示されます。
ここに画像の説明を挿入します

4. ノードサーバーを起動します

1. ダウンロード

npm i mongoose Express -D // Mongoose でカプセル化された mongodb、エクスプレス ミドルウェア
npm iソケット.io -S // クライアントとの通信を完了するためにソケット.io を使用します

2. 初期化

ルートディレクトリにフォルダー、メインファイルserverを含むフォルダーindex.jsmoduleフォルダー構成schame/modelなどを作成します。

moduleフォルダーには、User.js Room.js Records.jsデータベースの 3 つのテーブルに対応する 3 つの構成ファイルが保存されています。ここでusers rooms recordsデータベース
ここに画像の説明を挿入します
に接続し、サーバーを起動します。chatsocket

以下の点が挙げられます。

1.mongodbデータベース接続時、確立時にschame/mode初期化失敗が発生するため、ここでの確立時にはrequire同期ローディングを使用します。

2. データベースが一意制約 (unique) を使用する場合は、それを追加する必要がありますmongoose.set('useCreateIndex', true)。追加しないと、コンソールに警告が表示されます。

3. データベースの唯一の制約は_idです。これにより、型を転送する方法が提供されます。ObjectIdmongoosemongoose.Types.ObjectId

4. 「現在の文字列パーサーの使用は非推奨です」という警告を回避するにはuseNewUrlParser、 に設定します。trueURL

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設定しますuseUnifiedTopologytrue

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))
...

データベースに入って結果を表示すると、データが正常に挿入されたことがわかります。
ここに画像の説明を挿入します

5. 関連記事

おすすめ

転載: blog.csdn.net/Vue2018/article/details/107428772