成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

簡單聊聊前端開發(fā)中的熱更新原理

MingjunYang / 2015人閱讀

摘要:背景前端項目開發(fā)過程中熱更新的機制大家都知道,不知道你在開發(fā)的時候是否做了這方面的配置。其實熱更新的原理并不復雜,或者說很簡單。服務器和瀏覽器規(guī)定好消息的規(guī)則,是刷新頁面還是更新。另外對模塊熱更新和原理有興趣的可以研究下,后面可能也會介紹。

背景

前端項目開發(fā)過程中熱更新的機制大家都知道,不知道你在開發(fā)的時候是否做了這方面的配置。

相信接觸最多的就是 webpack 的熱更新,文件保存后頁面自動刷新,或者 css 自動更新,頁面的樣式在不刷新頁面的情況下就會更新。

還有就是模塊熱替換。

熱更新機制很好玩,能提升不少開發(fā)效率,但是只是處于會用的階段不是我們的目的,我們應該適當?shù)纳钊雽W習下,看看他背后的原理,一個是否思考過,一個是否能自己實現(xiàn)。

熱更新原理

咱們這里主要說下怎樣自己實現(xiàn)一個熱更新,也就是文件更改了會自動刷新頁面,可以同步 pc 和 移動端,css 更改了可以不刷新頁面就應用最新的 css。

其實熱更新的原理并不復雜,或者說很簡單。

咱們一步一步的分析下。

本文不是要告訴你一些 api如何使用,而是利用架構的思維去分析和解決問題。

【分析】

文件內(nèi)容變更了,瀏覽器是怎么知道的呢?

css 文件內(nèi)容變更了,沒有刷新頁面 怎么加載最新的內(nèi)容呢?

只要解決了上面兩個問題,我們就算是完成了。因為剩下得就是編碼了,這都好說。

【結果】

文件變更了,我怎樣通知瀏覽器?

瀏覽器和服務器保持著連接。 服務器有什么事兒直接通過當前的鏈接告訴瀏覽器就可以了。

連接肯定是長連接,不然怎么實時通信。

保持長連接有哪些方法呢? 輪詢?eventSorce? 都不夠好。

有么有更好的方案呢?那就是 - websocket

瀏覽器和服務器先建立好鏈接,服務器就可以直接通知到客戶端了。這個時候無論是 pc 上還是手機上都可以隨時根據(jù)需要刷新或者加載資源。

css 更新,css 本身是可以通過 dom 去操作的。瀏覽器只要知道是 css更新了,直接重新加載當前的 css 文件就可以了。

架構思維

咱們在重新捋捋這個架構。

服務器和瀏覽器通過 websocket 建立鏈接。

服務器和瀏覽器規(guī)定好消息的規(guī)則,是刷新頁面還是更新 css。

基本架構有了,其他的就是編碼實現(xiàn)了。

服務端使用 node 創(chuàng)建一個 ws 服務。

瀏覽器使用 websocket 創(chuàng)建一個鏈接和服務器進行鏈接。

雙方通過對應的 api 進行數(shù)據(jù)的操作。

代碼實現(xiàn)

本文只是講解下思路,并沒有實現(xiàn)文件的監(jiān)聽,文件監(jiān)聽后面會介紹。咱暫時先確定好兩個消息規(guī)則:

瀏覽器收到 命令為:htmlFileChange ,此時瀏覽器刷新;

瀏覽器收到命令為:cssFileChange,此時不刷新頁面,自動加載 css 文件;

具體代碼如下:

服務端:
//web-socket.js 創(chuàng)建 ws 服務
var ws = require("nodejs-websocket");//需要安裝這個包

module.exports = function(){
    return function () {
        console.log("重度前端提醒,開始建立連接...")

        var sessions = [];//存放每一個鏈接對象
        var server = ws.createServer(function (conn) {
            sessions.push(conn);//將新的鏈接對象存放在數(shù)組中

            conn.on("text", function (str) {
                console.log("收到的信息為:" + str)
                sessions.forEach(item=>{
                    item.sendText(str) //所有客戶端都發(fā)送消息
                });

            });
            conn.on("close", function (code, reason) {
                console.log("關閉連接")
            });
            conn.on("error", function (code, reason) {
                console.log("異常關閉")
            });
        }).listen(6152)
        console.log("WebSocket建立完畢")
    }
}

//server.js http 服務代碼

let http = require("http");
let fs = require("fs");
let webSocket = require("./node/web-socket");

const BASEROOT = process.cwd();//獲得當前的執(zhí)行路徑
//讀取 index.html內(nèi)容
let getPageHtml = function () {
    let data = fs.readFileSync(BASEROOT+"/html/index.html");
   return data.toString();
}
//讀取 index.css內(nèi)容
let getPageCss = function () {
    let data = fs.readFileSync(BASEROOT + "/html/index.css");
    return data.toString();
}

//node 端 開啟 ws 服務
webSocket()();

http.createServer(function (req, res) {//創(chuàng)建 http 服務

    let body = "",url = req.url;

    req.on("data", function (chunk) {
        body += chunk;
    });

    req.on("end", function () {
        //路由簡單處理 根據(jù)不同路徑輸出不同內(nèi)容給瀏覽器
        if(url.indexOf("/index.css")>-1){
            res.write(getPageCss());
        }else{
            res.write(getPageHtml());
        }

        res.end();

    });

}).listen(6151);

console.log("重度前端提醒...... server start");
頁面截圖

客戶端
//index.html 布局代碼省略

 const nick = ["a", "b", "c", "d", "e", "f", "g", "aa", "cc"];
    let index = 0;
    // Create WebSocket connection.
    const socket = new WebSocket("ws://10.70.69.191:6152");

    // Connection opened
    socket.addEventListener("open", function (event) {
        socket.send(navigator.userAgent);
    });

    // 監(jiān)聽服務器推送的消息
    socket.addEventListener("message", function (event) {
        if (index > nick.length) {
            index = 0;//只是為了每次輸出不同的昵稱,沒實際意義
        }

        var ele = document.createElement("div");
        ele.innerHTML = nick[index] + ":" + event.data;
        if (event.data === "htmlFileChange") {
            //html 文件更新了 刷新當前頁面
            location.reload();
        }
        if (event.data === "cssFileChange") {
            //css 文件更新了 刷新當前頁面
            reloadCss();
        }
        document.getElementById("content").append(ele);
        index += 1;
    });
    //重新加載 css
    function reloadCss() {
        var cssUrl = [],
            links = document.getElementsByTagName("link"),
            len = links.length;
        for (var i = 0; i < len; i++) {
            var url = links[i].href;
            document.getElementsByTagName("head")[0].appendChild(getLinkNode(url)); //創(chuàng)建新的 css 標簽
            document.getElementsByTagName("head")[0].removeChild(links[i]); //移除原有 css

        }
        console.log(document.getElementsByTagName("head")[0])

        function getLinkNode(cssUrl) {
            var node = document.createElement("link");
            node.href = cssUrl;
            node.rel = "stylesheet";
            return node;
        }
    }

    document.getElementById("btn1").onclick = function () {
        socket.send(document.getElementById("message").value);
        document.getElementById("message").value = "";
    }

index.css 內(nèi)容

 input {
      outline: none;
  }

  #content {
      height: 400px;
      width: 400px;
      border: solid 1px #ccc;
      color: red;
  }

代碼倒是次要的。解決問題的思路才重要。有了解決問題的架構思維,代碼實現(xiàn)都好說。

寫到這里咱們還能順便實現(xiàn)一個群聊。

本質就是服務器和瀏覽器怎樣實時通信,解決了這個問題,其他的都是小事兒。

這個技術實現(xiàn)還是比較簡單的。

另外對模塊熱更新和 websocket 原理有興趣的可以研究下,后面可能也會介紹。

總結

本文主要介紹

簡易版熱更新的原理;

熱更新實現(xiàn)思路和代碼實現(xiàn);

架構思維:簡單的帶出架構思維的作用;

希望本文對你有用。

原創(chuàng)不易、請多鼓勵
自家觀點、歡迎打臉

代碼示例下載

https://github.com/bigerfe/ho...

作者:微信公眾號 - 重度前端 主筆:八門
歡迎關注 重度前端-每周5原創(chuàng)全棧干貨+每周三深度技術文章

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/101478.html

相關文章

  • Node.js 前后端分離開發(fā)新思路

    摘要:從事開發(fā)的程序員,對于前后端分離模式多半不陌生,這也是目前主流的開發(fā)模式,具體關于前后端分離的模式可以參看文章你不得不了解的前后端分離原理,在這里寫者不進行說明。原理圖如下,前后端在一個進程同一個端口中,通過熱替換更新的,而不是全量重啟。 從事 Web 開發(fā)的程序員,對于前后端分離模式多半不陌生,這也是目前主流的 Web 開發(fā)模式,具體關于前后端分離的模式可以參看文章《你不得不了解的前...

    Lionad-Morotar 評論0 收藏0
  • Webpack 熱更新機制

    摘要:聯(lián)想到我在微信小程序上的開發(fā)體驗,真心覺得如果有熱更新機制的話,開發(fā)效率要高很多。熱更新示例下面通過例子來進一步解釋熱更新機制。 想必作為前端大佬的你,工作中應該用過 webpack,并且對熱更新的特性也有了解。如果沒有,當然也沒關系。 下面我要講的,是我對 Webpack 熱更新機制的一些認識和理解,不足之處,歡迎指正。 首先: 熱更新是啥? 熱更新,是指 Hot Module Re...

    mikasa 評論0 收藏0
  • 如何在前端項目中實現(xiàn)熱更新

    摘要:如果你的項目中使用了的話,你會很幸運,借助插件可以實現(xiàn)項目的熱更新。對模板更新的處理目前項目中使用的是的模板引擎。 showImg(https://segmentfault.com/img/bVrAa7);這個是組內(nèi)一位同學在平時開發(fā)中,發(fā)現(xiàn)調試不便,為團隊開發(fā)的熱更新工具。很厲害,文章中的技術實現(xiàn)內(nèi)容也是我了解了他的具體實現(xiàn)思路后,整理出來的。 工具源碼EHU(esl-hot-upd...

    antz 評論0 收藏0

發(fā)表評論

0條評論

MingjunYang

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<