做者:李帥傑javascript
插件功能:用於根據指定目錄文件變化自動刷新指定頁面的whistle插件。html
1、需求背景:前端
前端頁面聯調時,F5 做爲 web 開發經常使用刷新調試驅動鍵,已經深深入在每一個開發的心中。還在爲修改頁面不停的手動刷新而煩惱麼?還在尋找其餘 F5 替代方案麼?如何優雅的釋放 F5,請看下文~。java
2、目標拆解:node
假如咱們本身來開發一種替代 F5 的文件刷新方案,能夠從三個目標來分析:git
1)文件修改監聽——目標是刷新頁面,但頁面刷新的前提是代碼的變更修改,捕捉文件修改事件成爲咱們優先解決的問題;github
2)頁面刷新——頁面刷新很簡單,可是如何通知到頁面進行刷新呢;web
3)修改通知——這個是咱們須要解決的重點;npm
3、解決方案(whistle 插件採用 fs 而非 gulp,此處借 gulp 簡單介紹下原理):json
有了問題和目標,思考下每一個問題的解決方案:
1)文件修改監聽——
a、gulp 很是 nice 的自動化構建工具
b、node 的 fs 模塊(livereload 插件經過 fs 模塊實現監控)
c、其餘
2)頁面刷新——js 方法,location.reload(x);
3)修改通知——開啓本地 svr,瀏覽器長連接監聽(經常使用的觀察者模式);
基於 node svr+websock 服務
4、開發實戰:
方案已經枚舉好,接下來就是開發實踐:
(一)環境準備和代碼實現(代碼可在附件下載):
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)啓動服務,刷新瀏覽器啓動監聽
7)文件修改,觀察效果
(二)其餘解決方案實現及問題:
其餘經常使用方案**:**
實現和問題:
訪問 localhost:3000,查看本地未分離文件,適合重構開發;
5、基於 whistle 的 livereload 插件,讓刷新更優雅
經過上述實踐咱們釋放了 F5,可是打開項目目錄,發現新增了一堆的 js,跟咱們的項目格格不入,如何更優雅的釋放 F5 呢?
whistle 插件化——目前已經開發整理成了 whistle 插件,地址以下:
npm 地址:npm.taobao.org/package/whi…
此處感謝 avenwu 大神對 whistle 插件化的專業指導和支持~
1)如何安裝:
注意:whistle 須要升級到最新版本
npm i -g whistle.livereload
複製代碼
安裝後:
2)使用方案:
#pattern whistle.livereload://須要監控的項目目錄
daoju.qq.com/xxx/ whistle.livereload://D:\xxx\
複製代碼
關注【IVWEB社區】公衆號獲取每週最新文章,通往人生之巔!