在项目中,我们经常需要一个自动刷新的功能【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net。无论你使用 webpack-dev-s【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。erver 还是其他工具,不够,市面上的本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】工具都稍微有点复杂,会另外起一个端口,用【作者:唐霜】【原创不易,请尊重版权】于服务端和客户端相互通信。这在某些条件下未经授权,禁止复制转载。【转载请注明来源】反而不符合要求,有些情况下,我们只有一个【原创内容,转载请注明出处】【本文首发于唐霜的博客】端口可以使用,只能在当前服务基础上进行处原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。理。我专门写了一个 express 的中未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。间件来实现。
【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。const chokidar = require('chokidar'); // 除了其他依赖,还需要依赖这个,用于监听文件变动
// 开启保存自动刷新功能
if (livereload) {
app.use(createLiveReload({
matchUrls: [/^\/some/, '/index.html'],
renderFile: path.join(__dirname, 'www/index.html'),
watchFiles: path.join(__dirname, 'www/**/*'),
isReady: () => true,
}))
}
/**
* 创建一个 livereload 中间件
* @param {*} options
*/
function createLiveReload(options) {
const { matchUrls, renderFile, watchFiles, intervalTime = 1000, isReady } = options
let latest = Date.now()
let modified = latest
chokidar.watch(watchFiles, {
ignored: /(.*\.(map)$)|(\/vendor\/)/,
}).on('all', () => {
if (typeof isReady === 'function' && !isReady()) {
return
}
modified = Date.now()
})
return function(req, res, next) {
const { method, originalUrl } = req
if (method.toLowerCase() !== 'get') {
next()
return
}
const scriptUrl = '/_live-reload.js'
const url = URL.parse(originalUrl)
const { pathname } = url
if (pathname === scriptUrl) {
if (modified > latest) {
const content = `window.location.reload(true)`
latest = modified
res.end(content)
}
else {
const content = `
var currentScript = document.currentScript;
setTimeout(function() {
// 移除老的脚本
currentScript.parentNode.removeChild(currentScript)
// 插入新的脚本
const script = document.createElement('script')
script.src = '/_live-reload.js?v=' + Date.now()
document.body.appendChild(script)
}, ${intervalTime})
`
res.setHeader('content-type', 'application/json; charset=utf-8')
res.end(content)
}
}
else if (matchUrls.some(item => item instanceof RegExp ? item.test(pathname) : item === pathname)) {
fs.readFile(renderFile, (err, data) => {
if (err) {
res.sendStatus(404);
}
else {
const html = data.toString()
const body = html.indexOf('</body>')
const script = `<script src="${scriptUrl}"></script>`
if (body > -1) {
const content = html.replace('</body>', script + '</body>')
res.end(content)
}
else {
const content = html + script
res.end(content)
}
}
})
}
else {
next()
}
}
}
实现原理,就是在前端界面不断的移除,新增著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】脚本,脚本的内容由服务端输出,在服务端文【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net件变化时,脚本内容为 window.lo【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。cation.reload(true) 【本文受版权保护】转载请注明出处:www.tangshuang.net从而刷新页面。
【本文首发于唐霜的博客】【本文受版权保护】【转载请注明来源】本文版权归作者所有,未经授权不得转载。需要注意两个点:【原创不易,请尊重版权】
原创内容,盗版必究。【转载请注明来源】【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】【转载请注明来源】- 由于它会直接读取文件后立即渲染,所以,在本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】 express 的路由列表中,要注意其【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。顺序,放在
app.use(express.static(...))后面,这样可以保证静态文件都可以被访问【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net到,放在其他所有动态路由的前面,这样能保【作者:唐霜】【版权所有】唐霜 www.tangshuang.net证通过 matchUrls 匹配到的 u【本文首发于唐霜的博客】【转载请注明来源】rl 能够使用 renderFile 进【本文受版权保护】【本文首发于唐霜的博客】行渲染 著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】【版权所有,侵权必究】【原创内容,转载请注明出处】原创内容,盗版必究。
- 你可能需要根据不同的 url 渲染不同的【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】文件,此时,你要多次调用 createL【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.netiveReload 来实现多个中间件实例本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。,当然,这个时候你要保证 matchUr【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。ls 的顺序是正确的。 【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。【版权所有,侵权必究】
这就是简单的自刷新中间件了。未经授权,禁止复制转载。
【本文首发于唐霜的博客】【未经授权禁止转载】【本文首发于唐霜的博客】原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net
