主頁 > 軟體設計 > es6模塊化,websoket(附簡易聊天室原始碼)以及webpack的詳細使用

es6模塊化,websoket(附簡易聊天室原始碼)以及webpack的詳細使用

2021-10-17 08:00:51 軟體設計

一、es6模塊化

1.1 使用es6模塊化步驟:

(1) 使用export暴露資料

(2) 使用import引入模塊

(3) 在html中引入js檔案,注意為script的屬性設定 type="module"

1.2 export

1.2.1 暴露

單個暴露語法1:

export let 變數1=值1;  
export var 變數2=值2; 
export function(){}
...

批量暴露語法2:

let 變數1 = 值1;
let 變數2 = 值2;
function 方法名(){}
...
?
export {變數1,變數2,方法名,,}

描述:暴露多個資料,注意變數的名稱和暴露的名稱一致

1.2.2 引入

語法:

import { 變數 }  from 檔案  
import { 變數 as  新變數名 } from 檔案

描述:加載模塊

1.3 export default

1.3.1 暴露

默認暴露語法:

export default 內容

描述:只暴露一個資料

注意:默認暴露在同一個檔案中能使用一次

1.3.2 引入

語法:

import 變數 from "檔案路徑"

二、websocket

2.1 websocket介紹【重點】

websocket是HTML5新增的協議,使用websocket協議可以使客戶端與服務器進行雙向通信,也就是除了客戶端可以發送訊息給服務器外,服務器也可以主動推送訊息給客戶端,

在websocket之前可以使用ajax+定時器來實作聊天室的這種類似功能,

2.2 socket.io模塊

使用步驟:

(1)下載socket.io

npm install socket.io@2

(2)使用express搭建服務器并配置socket.io

(3)配置客戶端

(4)訪問服務器建立連接

(5)業務代碼

2.3 常用方法

2.3.1 webSocket

語法:

let webSocket = require('socket.io')
webSocket(server)

描述:回傳socket.io物件,引數server為app.listen回傳的server物件

2.3.2 io

語法:

io( websocket服務器地址 )

描述:客戶端與服務器端建立連接

2.3.3 on:接收訊息

語法1:

io.on( 'connect',callback )

描述1:語法1為當用戶連接服務器則觸發connect事件,注意:前端需要 io( websocket服務器地址 )

語法2:

websocketObj.on( event,callback )

描述2:語法2為客戶端兼聽服務器端發送過來的訊息,也可以是服務器端兼聽客戶端發過來的訊息

2.3.4 emit:發送訊息

語法1:

websocketObj.emit( 事件,訊息物件 )

描述1:觸發事件并發送訊息

語法2:

io.sockets.emit(事件,訊息物件)

描述2:觸發所有客戶端兼聽的事件并發送訊息

2.3.5 join:加入房間

語法:

webSocketObj.join(房間id,事件回呼)

描述:加入房間

2.3.6 to:將訊息發送到指定的房間中

語法:

io.to( 房間號 ).emit( 事件,訊息物件 )

描述:觸發物件房間號的用戶事件,并發送訊息

2.4 群聊

服務端的代碼:

const express = require('express');
const path = require('path');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
//監聽事件:是否有新的websocket連接
io.on('connection', (socket) => {
    //接收客戶端發送的訊息:
    socket.on('chat', d => {
        //console.log(d, 999);
        //服務器將接收到的訊息推送給所有客戶端:io.emit()
        io.emit('rechat', d);
    });
});
server.listen(3000);
//處理用戶登錄聊天室
app.get('/login', (req, res) => {
    let { usr = '' } = req.query;
    if (usr == '') {
        res.send(`<script>alert('用戶名不能為空');location.href='login.html';</script>`);
        return;
    }
    res.cookie('UNAME', usr); //將用戶名保存到cookie中
    res.send(`<script>location.href='2-chat.html';</script>`);
});


//開放靜態資源
app.use(express.static(path.join(__dirname, 'www')))

客戶端的代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="socket.io/socket.io.js"></script>
    <style>
        div {
            position: fixed;
            left: 20px;
            bottom: 20px;
            background-color: blanchedalmond;
            padding: 10px;
        }
    </style>
</head>

<body>
    <ul>
        <!-- <li>XXX說:???</li>
        <li>XXX說:???</li> -->
    </ul>
    <div>
        <input type="text" id="msg">&nbsp;
        <input type="button" value="發送" id="btn">
    </div>
    <script>
        let socket = io(); //創建websocket連接
        let btnObj = document.getElementById('btn');
        let msbObj = document.getElementById('msg');
        let ulObj = document.getElementsByTagName('ul')[0];
        btnObj.onclick = function() {

            let curUser = ''; //當前已登錄的用戶名
            let cookieValue = document.cookie; //獲取cookie
            if (cookieValue.indexOf('UNAME') == -1) { // 未登錄
                alert('請先登錄');
                location.href = 'login.html';
            } else { //已登錄
                let arr = cookieValue.split(';');
                for (let val of arr) {
                    if (val.indexOf('UNAME') != -1) {
                        let arr2 = val.split('=');
                        curUser = arr2[1];
                    }
                }
            }
            let msgVal = msbObj.value; //獲取用戶輸入的聊天內容
            if (msgVal != '') {
                socket.emit('chat', `${curUser}說:${msgVal}`); //發送訊息給服務器
            }
        }
        //客戶端接收服務器推送的訊息:
        socket.on('rechat', data => {
            //console.log(data, 1111);
            ulObj.innerHTML = `<li>${data}</li>` + ulObj.innerHTML;
        });
    </script>
</body>

</html>

2.5 磁區(分房間)通信

服務端的代碼如下:

const express = require('express');
const path = require('path');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', (socket) => {
    // console.log( socket.handshake.query );
    let roomid = socket.handshake.query.roomid //接收房間號
    //2. 當前連接上的用戶加入某一個房間
    socket.join(roomid, () => {
        // console.log('加入房間成功:' + roomid)
        socket.emit('event1', '加入成功')
    })
    socket.on('front_message1', (message) => {
        // console.log(message, 8888);
        io.to(roomid).emit('server_message1', message) //點對點
    })
})
server.listen(3000);
//托管靜態資源
app.use(express.static(path.join(__dirname, 'www')));

客戶端代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="text" id="roomid" placeholder="輸入房間號">
    <button id="rooms">加入房間</button>
    <input type="text" id="msg" placeholder="輸入訊息內容">
    <button id="btn">發送訊息</button>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
        let socket = null
            //1. 點擊加入房間按鈕,然后和socket服務器建立連接
        $('#rooms').click(function() {
            if ($('#roomid').val() == '') {
                alert('請輸入房間號')
                return
            }
            //創建連接,并且告訴服務器要加入一個房間
            socket = io('http://localhost:3000?roomid=' + $('#roomid').val());
            // 客戶端兼聽事件
            socket.on('server_message1', (message1) => {
                console.log(message1)
            })
            //服務端加入房間后觸發此事件,告訴客戶端
            socket.on('event1', (message) => {
                alert(message)
            })
        })
        $('#btn').click(function() {
            if (!socket) {
                alert('請加入一個房間')
                return
            }
            //觸發服務器端的事件,發送訊息
            socket.emit('front_message1', $('#msg').val())
        })
    </script>
</body>

</html>

三、webpack

3.1 webpack概念

Webpack 前端資源模塊化管理和打包工具,可以將許多松散的模塊按進行打包成線上環境所需的前端資源,同時webpack依賴node環境 ,webpack對一些模塊的版本要求非常嚴格

注意:webpack是前端開發者需要的一個工具,

開發環境

生產環境

3.1.1為什么學習webpack

3.2 準備作業

webpack官網 webpack 中文檔案 | webpack 中文網

(1)安裝node

(2)安裝webpack和webpack-cli , npm i webpack@4 webpack-cli@3 -g

(3)檢查webpack是否安裝成功 , webpack --version

3.3 webpack核心介紹

鍵名概念解釋
context入口起點基礎目錄,絕對路徑,用于從配置中決議入口起點(entry point)
entry入口 (必須)配置打包入口檔案的名字
output出口 (必須)打包后輸出到哪里, 和輸出的檔案名
module加載器配置在rules對應陣列中, 定義物件規則
plugins插件配置配置插件功能(插件有著webpack不具備的某些功能,比如:壓縮html檔案)

3.3.1 webpack.config.js 語法格式

module.exports = {
    context:入口起點,
    entry:入口,
    output:{
        path:出口目錄,
        filename:檔案名,
    },
    module: { 
        rules: [ 
            加載器規則 
        ]
    },
    plugins:[
        插件
    ]
}

3.4 webpack使用

3.4.1 初識webpack進行打包js

3.4.2 css處理

loader的認識

步驟:

css-loader 3版本 style-loader 2版本

npm i css-loader@3 style-loader@2 -D

devDependencies:

dependencies:

module: {
	rules: [ 
		{ 
			test: /\.css$/, 
			use: [ 'style-loader', 'css-loader' ]
		}
	]
}

3.4.3 分離css

extract-text-webpack-plugin@next 插件

安裝下載

npm i extract-text-webpack-plugin@next -D

加載器修改配置

const ExtractTextPlugin = require("extract-text-webpack-plugin"); 
rules: [ // 加載器的使用規則
	{
		test: /\.css$/,
		use: ExtractTextPlugin.extract({ // 從一個已存在的 loader 中,創建一個提取(extract) loader,
			fallback: "style-loader", 
        	use: "css-loader"  // loader被用于將資源轉換成一個CSS單獨檔案
        })
	}
]

插件配置

new ExtractTextPlugin("style.css"), // 輸出的檔案名

報錯說明:

Error: Cannot find module 'webpack/lib/Chunk'

解決方案:在專案目錄下下載webpack@4

3.4.4 打包less

  1. 需要安裝less 和 less-loader 來決議less代碼, 和加載less檔案

    npm i less@3 less-loader@7 -D
  2. 在webpack.config.js中 配置加載器, 決議.less檔案

    { 
    	test: /\.less$/, 
    	use: ['style-loader', 'css-loader', "less-loader"]
    }
  3. 但是這樣發現css代碼沒有分離出來, 所以還需要使用extract-text-webpack-plugin的配置, 分離出css代碼

    { 
    	test: /\.less$/, 
    	use: ExtractTextPlugin.extract({ 
    		fallback: "style-loader", 
    		use: ['css-loader', "less-loader"]
    	})
    }
  4. 觀察打包后style.css中多了less檔案里的樣式代碼

3.4.5 生成html

html-webpack-plugin插件,

下載

npm i html-webpack-plugin@4 -D

注意:插件需要顯示的引入到webpack.config.js中

plugins屬性

plugins:[
        new HtmlWebpackPlugin({ // 插件配置物件
            filename: "index.html", // 產出檔案名(在dist目錄查看)
            template: __dirname + "/index.html", // 以此檔案來作為基準(注意絕對路徑, 因為此檔案不在src下)
            favicon: "./assets/favicon.ico", // 插入打包后的favicon圖示
            minify: {                             //對html檔案進行壓縮,
                    collapseBooleanAttributes: true,  //是否簡寫boolean格式的屬性如:disabled="disabled"簡寫為disabled
                    minifyCSS: true,                  //是否壓縮html里的css(使用clean-css進行的壓縮) 默認值false
                    minifyJS: true,                   //是否壓縮html里的js(使用uglify-js進行的壓縮)
                    removeAttributeQuotes: true,      //是否移除屬性的引號 默認false
                    removeComments: true,             //是否移除注釋 默認false
                    removeCommentsFromCDATA: true,    //從腳本和樣式洗掉的注釋, 默認false
             }
        }) // 陣列元素是插件的new物件
    ]

如果報錯說明

Cannot find module "webpack/lib/node/NodeTeplatePlugins"

在安裝html-webpack-plugin插件的工程中, 單獨的在本地安裝一下跟全域webpack對應的版本

npm i webpack@4 -D

3.4.6 靜態資源處理

  1. 需要下載2個加載器模塊

    • url-loader、file-loader

下載:

npm i url-loader@4 file-loader@6 -D

注意: webpack認為, 圖片也是一個模塊, 所以才需要loader來決議圖片)

2.webpack.config.js加載器配置:

在module中加上此配置,

 {
     test: /\.(png|jpg|jpeg|gif|svg)$/, // 處理這些結尾的檔案
     use: 'url-loader'
 }

// 如果處理字體圖示需要引入這個
{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url-loader'
}

3.4.7 jquery使用

在webpack打包的專案中, 使用jQuery功能

  1. 下載jquery模塊,

    npm i jquery

  2. 在main.js中引入jquery,

    import $ from 'jquery'

3.4.8 熱更新

  1. webpack-dev-server會實時監聽檔案變化, 自動打包到記憶體中, 而不是生成硬碟上的dist目錄

  2. webpack-dev-server 它還會啟動一個本地的服務器, 來支持你訪問打包后的html網頁

    • 下載webpack-dev-server -g

    • npm i webpack-dev-server -g

    • webpack-dev-server --version

  3. 在專案下運行 命令: webpack-dev-server 可啟動熱更新服務器, 會根據目錄下的webpack.config.js,只是在記憶體中運行起來了,

  4. 注意: 如果修改了配置(webpack.config.js)檔案, 還是需要重啟終端, 如果是src下的代碼, 會自動打包

  5. 注意: 默認需要打包輸出的檔案名必須為 index.html檔案

  6. 默認在埠號:8080上啟動我們熱更新服務器, 專案都在這個服務器上打開訪問

  7. 當開發完畢還需要使用webpack命令進行打包到dist目錄 ,

webpack.config.js配置:

devServer: { // 在這里可以對webpack-dev-server進行一些配置
        port: 9090, //修改埠號,默認為8080
        open: true, // 自動呼叫默認瀏覽器打開
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/319680.html

標籤:其他

上一篇:詳解SQL Server分布式查詢

下一篇:Python學習日志——TCP網路應用程式開發流程

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more