前端开发 - 热更新原理

提出问题

  • 文件内容变更了,浏览器是怎么知道的呢?
  • css 文件内容变更了,没有刷新页面 怎么加载最新的内容呢?

结论

websocket
浏览器和服务器先建立好链接,服务器就可以直接通知到客户端了。这个时候无论是 pc 上还是手机上都可以随时根据需要刷新或者加载资源。

实现思维

  • 服务器和浏览器通过 websocket 建立链接。
  • 服务器和浏览器规定好消息的规则,是刷新页面还是更新 css。

1.服务端使用 node 创建一个 websocket 服务。
2.浏览器使用 websocket 创建一个链接和服务器进行链接。
3.双方通过对应的 api 进行数据的操作。

实现思路

浏览器收到命令为:htmlFileChange ,此时浏览器刷新;
浏览器收到命令为:cssFileChange,此时不刷新页面,自动加载 css 文件;

服务端
//web-socket.js 创建 ws 服务
var ws = require("nodejs-websocket");//需要安装这个包

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

        var sessions = [];//存放每一个链接对象
        var server = ws.createServer(function (conn) {
            sessions.push(conn);//将新的链接对象存放在数组中

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

            });
            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();//获得当前的执行路径
//读取 index.html内容
let getPageHtml = function () {
    let data = fs.readFileSync(BASEROOT+'/html/index.html');
   return data.toString();
}
//读取 index.css内容
let getPageCss = function () {
    let data = fs.readFileSync(BASEROOT + '/html/index.css');
    return data.toString();
}

//node 端 开启 ws 服务
webSocket()();

http.createServer(function (req, res) {//创建 http 服务

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

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

    req.on('end', function () {
        //路由简单处理 根据不同路径输出不同内容给浏览器
        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);
    });

    // 监听服务器推送的消息
    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)); //创建新的 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 = '';
    }

代码地址:https://github.com/bigerfe/hotUpdate-demo

原文链接: 简单聊聊前端开发中的热更新原理

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,859评论 1 45
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,842评论 1 92
  • 前端开发面试知识点大纲: HTML&CSS: 对Web标准的理解、浏览器内核差异、兼容性、hack、CSS基本功:...
    秀才JaneBook阅读 2,591评论 0 25
  • 转载自:http://web.jobbole.com/82197/ 前端的性能对于一个Web应用来说非常重要,如果...
    天字一等阅读 631评论 0 2
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,267评论 4 61