未加星标

Liveload:用Node.js实现页面热加载

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二03 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

我们在开发前端页面时,修改了样式表之后都会到浏览器手动刷新页面看修改后的效果。但是这样非常繁琐而且非常耗时。尤其是在各种设备上测试不同的浏览器时更是如此。而使用Node.js可以帮助我们实现页面热加载,点击一下保存,所有打开的页面都会刷新,是不是爽歪歪!

我们先来回顾一下前段开发的经典流程:

在多个浏览器打开页面; 寻找页面上需要调整的样式; 修改一个或多个样式; 手动刷新每个浏览器中的页面; 返回第2步。

其中第4步非常的繁琐,需要在每个浏览器中手动刷新页面,如果是在移动设备上测试,就更加耗时间了。

但是如果能完全去掉手动刷新这一步呢?想象一下,当在文本编辑器中保存样式表时,所有打开了那个页面的浏览器都会自动重新加载这个CSS样式表。这会帮节省大量时间。

下面我们就使用 Socket.IO 跟Node.js的 fs.watchFile() 和 fs.watch() 函数配合,让这个想法变成现实。

关于 Socket.IO 大家可以看我这篇翻译至官网的文章了解一下。

fs.watchfile() 与 fs.watch() 是Node.js中两个监测文件的API(包括内容改动和名字、时间戳等的任何变化)。

fs.watchfile() 通过轮询检测文件的变化,所以它更耗资源,而且反应有个时间差;但是它是跨平台的,在所有系统上的表现都一样。 fs.watch() )是通过监听操作系统提供的各种”事件”(内核发布的消息)实现的,针对每个平台做了高度优化,但在每个平台上的表现是不同的,导致这个方法不能保证在所有平台上可用。

所以两种方法我都会讲到。

下面开始实现这个应用。

构建web服务器

我们使用 Koa 框架和 Socket.IO 结合在一起,构建一个静态Web服务器。

安装依赖

首先新建一个 auto-reload 文件夹,然后在文件夹下新建一个 package.json 文件,将下面内容复制到文件中:

{ "name": "liveload", "version": "0.0.1", "description": "Let the page automatically reload.", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "koa": "^2.0.0-alpha.7", "koa-convert": "^1.2.0", "koa-static": "^2.0.0", "socket.io": "^1.7.1" } }

然后运行 npm install 安装依赖。

编写静态服务器

新建 index.js 文件并将下面内容复制到文件中:

const Koa = require('koa'); const convert = require('koa-convert'); const statc = require('koa-static'); const app = new Koa(); app .use(async(ctx, next) => { console.log(ctx.path); await next(); }) // 将服务器设置为基本的静态文件服务器 .use(convert(statc(__dirname))); app.listen('9000', () => { console.log('Server running at post 9000.') })

新建 index.html 文件并将下面内容复制到文件中:

<!DOCTYPE html> <htmllang="en"> <head> <metacharset="UTF-8"> <title>liveload</title> <linkrel="stylesheet"href="/css/style.css"> </head> <body> <h1>This is our Awesome Webpage!</h1> <divid="body"> <p> If all the file is edited, then the server will send a message to the brower using Socket.IO telling it to refresh the page. </p> </div> </body> </html>

新建 css 文件夹,然后在该文件夹下新建 style.css 文件,写下如下样式:

h1{ color:red; }

这样静态文件服务器就搭建好了。

因为我使用了 async await 语法,所以 node 7.0 以上的版本可以运行 node --harmony-async-await index 运行脚本, node 7.0 以下的版本就需要用 babel 来转码了,安装以下依赖:

npm i -S babel-core npm i -S babel-polyfill npm i -S babel-preset-es2015 npm i -S babel-preset-stage-3

新建 start.js 文件,然后复制以下内容到文件:

require("babel-core/register")({ presets: ['stage-3', 'es2015'] }); require("babel-polyfill"); require("./index.js");

然后运行 node start 启动脚本。

启动脚本后在浏览器打开 localhost:9000 就可以看见页面了。

同时控制台会输出如下内容

/ /css/header.css

这样脚本就会获得请求的文件,然后对每个文件进行监听。

设置文件监听

下面就是设置文件监听的方法了。

创建一个监听函数用来监听文件:

const path = require('path'); const fs = require('fs'); let wathcers = {}; functioncreateWatch(file){ if (file === '/') file = 'index.html'; let absolute = path.join(__dirname, file); if (wathcers[absolute] === true) return; fs.watch(absolute, (e, filename) => { console.log(e); }); wathcers[absolute] = true; }

上面是用 fs.watch() 方法写的,如果用 fs.watchFile() 写法如下:

fs.watchFile(absolute, (curr, prev) => { if (curr.mtime.getTime() !== prev.mtime.getTime()) { console.log(e); } });

因为直接访问 localhost:9000 是访问的 index.html 文件,所以解析到 index.html ;然后用 path.join() 获得文件的绝对路径,用 fs.watch() 监听。回调函数中的 e 是对文件做出的修改事件, filename 是文件名。如果对文件进行了修改,那么就会输出 e 为: change 。

为了防止重复监听,定义一个 wathcers 对象,每监听一个文件,就将这个文件放进对象中,将值设为 true 。然后前段请求的文件判断有没有监听,如果已监听就返回,不再重复监听。

接着修改第一个中间件如下:

app .use(async(ctx, next) => { let file = ctx.path; await next(); createWatch(file); })

这样当你访问完了 localhost:9000 之后,对 index.html 和 style.css 做修改,都会在控制台输出: change 。

用Socket.IO重载

下面就是用Socket.IO向页面发送文件修改过的消息,让页面重载了。

首先引入 socket.io 并整合到服务器上:

const socket = require('socket.io'); const app = new Koa(); const server = http.Server(app.callback()); const io = socket(server); server.listen('9000', () => { console.log('Server running at post 9000.') });

然后在监听函数里修改:

fs.watch(absolute, (e, filename) => { if (e === 'change') { console.log(e); io.sockets.emit('reload'); } });

同时在 index.html 的 <head> 标签里加上如下代码:

<scriptsrc="/socket.io/socket.io.js"></script> <script> window.onload = function(){ const socket = io(); socket.on('reload', () => { window.location.reload(); }) } </script>

好了,重启脚本然后试验了,比如说在打开 localhost:9000 后修改css文件,就会看到保存后页面就会刷新。

全部代码 index.js const fs = require('fs'); const Koa = require('koa'); const http = require('http'); const path = require('path'); const convert = require('koa-convert'); const statc = require('koa-static'); const socket = require('socket.io'); const app = new Koa(); const server = http.Server(app.callback()); const io = socket(server); app .use(async(ctx, next) => { let file = ctx.path; await next(); createWatch(file); }) // 将服务器设置为基本的静态文件服务器 .use(convert(statc(__dirname))); server.listen('9000', () => { console.log('Server running at post 9000.') }); let wathcers = {}; functioncreateWatch(file){ if (file === '/') file = 'index.html'; let absolute = path.join(__dirname, file); if (wathcers[absolute] === true) return; fs.watch(absolute, (e, filename) => { if (e === 'change') { console.log(e); io.sockets.emit('reload'); } }); wathcers[absolute] = true; } index.html: <!DOCTYPE html> <htmllang="en"> <head> <metacharset="UTF-8"> <title>liveload</title> <linkrel="stylesheet"href="/css/style.css"> <scriptsrc="/socket.io/socket.io.js"></script> <script> window.onload = function(){ const socket = io(); socket.on('reload', () => { window.location.reload(); }) } </script> </head> <body> <h1>This is our Awesome Webpage!</h1> <divid="body"> <p> If all the file is edited, then the server will send a message to the brower using Socket.IO telling it to refresh the page. </p> </div> </body> </html> /css/style.css: h1{ color:blue; }

好了,打完收工。

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

分页:12
转载请注明
本文标题:Liveload:用Node.js实现页面热加载
本站链接:http://www.codesec.net/view/524479.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(23)