让前端飞Web 前端开发

前端开发 - 热更新原理

2019-04-07  本文已影响5人  alanwhy

提出问题

结论

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

实现思维

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

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

上一篇下一篇

猜你喜欢

热点阅读