53

F5键已抠的我,根本不慌!(基于whistle的livereload)

 4 years ago
source link: https://www.tuicool.com/articles/3YVVfmR
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

插件功能:用于根据指定目录文件变化自动刷新指定页面的whistle插件。

一、需求背景:

前端页面联调时,F5 作为 web 开发常用刷新调试驱动键,已经深深刻在每个开发的心中。还在为修改页面不停的手动刷新而烦恼么?还在寻找其他 F5 替代方案么?如何优雅的释放 F5,请看下文~。

N7zIZ3N.jpg!web

二、目标拆解:

假如我们自己来开发一种替代 F5 的文件刷新方案,可以从三个目标来分析:

MjeIVvV.jpg!web

1)文件修改监听——目标是刷新页面,但页面刷新的前提是代码的变动修改,捕捉文件修改事件成为我们优先解决的问题;

2)页面刷新——页面刷新很简单,但是如何通知到页面进行刷新呢;

3)修改通知——这个是我们需要解决的重点;

三、解决方案(whistle 插件采用 fs 而非 gulp,此处借 gulp 简单介绍下原理):

有了问题和目标,思考下每个问题的解决方案:

RZbIbqF.jpg!web

1)文件修改监听——

a、gulp 非常 nice 的自动化构建工具

官网:https://www.gulpjs.com.cn/

b、node 的 fs 模块(livereload 插件通过 fs 模块实现监控)

c、其他

2)页面刷新——js 方法,location.reload(x);

3)修改通知——开启本地 svr,浏览器长链接监听(常用的观察者模式);

基于 node svr+websock 服务

四、开发实战:

方案已经枚举好,接下来就是开发实践:

(一)环境准备和代码实现(代码可在附件下载):

1)项目目录下,安装需要的 js 模块

npm i -s gulp
npm i -s ws

2)服务端代码编写

const WebSocket = require('ws');
const port = 8080;
function startSvr() {
    console.log("start svr port:"+port);
    var wss = new WebSocket.Server({
        port: port
    });
    var connection = {};
    wss.on('connection', function(ws) {
        console.log("ws 已经连接");
        ws.on('message', function(message) {
            console.log("收到message:"+message);
            msg = JSON.parse(message);
            if (msg.type === 'test') {
                connection[msg.id] = ws;
                console.log('received: %s', JSON.stringify(msg));
                if (!!connection[msg.id]) connection[msg.id].send(JSON.stringify(msg));
            } else {
                wss.clients.forEach(function each(client) {
                    client.send(message);
                });
            }
        });
    });
}
module.exports = {
    start:startSvr
};

3)客户端监听代码编写

var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function() {
    console.log('open');
};
ws.onclose = function() {
    console.log('onclose');
};
ws.onmessage = function(event) {
    console.log('event,', event.data); //拿到的返回数据
    var json = JSON.parse(event.data);
    if(json.command=="reload"){
        location.reload(1);
    }else if(json.command=="javascript"){
        eval(json.text);
    }else if(json.command=="replace"){
        document.getElementsByTagName("html")[0].innerHTML = json.text;
    }
};

4)gulp 监听配置文件编写( 此处 gulp 采用 4.0.2 版本

const {
    series,
    parallel,
    watch,
    src,
    dest
} = require('gulp');
const WebSocket = require('ws');
const appsvr = require('./appsvr.js');
const watcher = watch(['*']);//此处监听目录下所有文件
// const fs = require('fs');
let ws = "";
//日志工具类
let showlog = function (svr) {
    var des = "";
    for (var name in svr) {
        des += name + ":" + svr[name] + ";\n";
    }
    console.log(des);
};
//服务开启
function webserver() {
    appsvr.start();
    setTimeout(function () {
        ws = new WebSocket('ws://localhost:8080');
        ws.on('open', () => {
            let msg = {
                command: 'init',
                text: ""
            };
            ws.send(JSON.stringify(msg));
        });
        ws.on('error', err => {
            console.log(err);
        });
        ws.on('message', data => {
            console.log(data);
        });
        ws.on('close', (code, reason) => {
            console.log(code);
            console.log(reason + ':' + typeof reason);
        });
    }, 2000);
}
//监听文件变化
watcher.on('change', function (path, stats) {
    console.log(`File ${path} was changed`);
    //发送给监听者的动作
    let msg = {
        command: 'reload',
        text: "reload"
    };
    ws.send(JSON.stringify(msg));
});
exports.webserver = webserver;
//默认触发,相当于main函数
exports.default = parallel(function () {
    console.log("running");
}, webserver);

5)客户端 js 监听文件如何嵌入页面?

a、通过 script 标签的方式手动嵌入,需要手动修改文件,且事后容易忘记删除;

<script type=“text/javascript” src=“./f5.js”></script>

b、基于 whistle 的优雅嵌入,会自动对匹配的页面(html)无感知嵌入指定 js:

whistle 命令:jsAppend

daoju.qq.com/xxx/   jsAppend://daoju.qq.com/xxx/js/f5.js

6)启动服务,刷新浏览器启动监听

IvAj6na.jpg!web

7)文件修改,观察效果

qYNname.jpg!web

(二)其他解决方案实现及问题:

其他常用方案

fUJnEvN.jpg!web

实现和问题:

  • 实现方式:通过插件生成的本地服务地址来进行自动刷新访问,比如:

访问 localhost:3000,查看本地未分离文件,适合重构开发;

  • 问题:活动开发前端联调是以线上活动域名 url 访问来进行开发和测试,且需要配合 host 配置,就不太适合。

五、基于 whistle 的 livereload 插件,让刷新更优雅

通过上述实践我们释放了 F5,但是打开项目目录,发现新增了一堆的 js,跟我们的项目格格不入,如何更优雅的释放 F5 呢?

whistle 插件化——目前已经开发整理成了 whistle 插件,地址如下:

npm 地址:

https://npm.taobao.org/package/whistle.livereload

此处感谢 avenwu 大神对 whistle 插件化的专业指导和支持~

1)如何安装:

注意:whistle 需要升级到最新版本

npm i -g whistle.livereload

安装后:

aquuyef.jpg!web

2)使用方案:

#pattern  whistle.livereload://需要监控的项目目录
daoju.qq.com/xxx/ whistle.livereload://D:\xxx\

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK