美文网首页让前端飞Web 前端开发
前端开发 - 热更新原理

前端开发 - 热更新原理

作者: alanwhy | 来源:发表于2019-04-07 22:08 被阅读5次

提出问题

  • 文件内容变更了,浏览器是怎么知道的呢?
  • 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

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

相关文章

  • 前端开发 - 热更新原理

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

  • Xcode开发高效率工具InjectionIII

    前端开发及安卓开发等,都自带有热重载HotReloading功能:开发时更改代码后执行保存操作就能实时更新程序,而...

  • 前端文章- 收藏集 - 掘金

    GitHub 上学习前端开发的资料(不定期更新) - 前端 - 掘金GitHub 上学习前端开发的资料(不定期更新...

  • 热更新原理

    文章参考自: https://blog.csdn.net/mycwq/article/details/132907...

  • 热更新原理

    文件监听-自带方式 1 .源码发生变化时,自动构建出新的输出文件2 .开启方式 3 .原理 webpack-dev...

  • android更新

    ## android更新 ## 导航 - ### 热更新 >- [x] 热修复简介 >- [x] 技术原理及特点 ...

  • 工程化学习路线

    Web开发 基础:web工作原理、git使用、idea(pycharm)等开发者工具 前端、网络、后端 前端(客户...

  • JSPath热更新和热修复 个人小结

    热更新和热修复 个人小结 热修复和热更新 1 热更新和热修复:在线修复程序的 BUG 2 JSPach 的使用原理...

  • Web前端热更新

    热更新是什么? 简单来说,热更新一般是指手机里的app有小规模更新,以直接打补丁的形式更新。相对应的,另一种更新方...

  • iOS开发-javaScript交互

    前言 当前混合开发模式迎来了前所未有的发展,跨平台开发、热更新等优点决定了这种模式的重要地位。虽然前端界面在交互、...

网友评论

    本文标题:前端开发 - 热更新原理

    本文链接:https://www.haomeiwen.com/subject/zpveiqtx.html