在项目中,我们经常需要一个自动刷新的功能本文作者:唐霜,转载请注明出处。原创内容,盗版必究。。无论你使用 webpack-dev-s未经授权,禁止复制转载。【作者:唐霜】erver 还是其他工具,不够,市面上的【本文首发于唐霜的博客】原创内容,盗版必究。工具都稍微有点复杂,会另外起一个端口,用本文作者:唐霜,转载请注明出处。【作者:唐霜】于服务端和客户端相互通信。这在某些条件下【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】反而不符合要求,有些情况下,我们只有一个【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。端口可以使用,只能在当前服务基础上进行处【版权所有,侵权必究】未经授权,禁止复制转载。理。我专门写了一个 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()
}
}
}
实现原理,就是在前端界面不断的移除,新增【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。脚本,脚本的内容由服务端输出,在服务端文著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。件变化时,脚本内容为 window.lo【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.netcation.reload(true) 【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。从而刷新页面。
本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】未经授权,禁止复制转载。需要注意两个点:原创内容,盗版必究。
【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net【本文受版权保护】- 由于它会直接读取文件后立即渲染,所以,在未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net express 的路由列表中,要注意其原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。顺序,放在
app.use(express.static(...))后面,这样可以保证静态文件都可以被访问【本文受版权保护】【版权所有】唐霜 www.tangshuang.net到,放在其他所有动态路由的前面,这样能保未经授权,禁止复制转载。【原创不易,请尊重版权】证通过 matchUrls 匹配到的 u【作者:唐霜】【关注微信公众号:wwwtangshuangnet】rl 能够使用 renderFile 进本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】行渲染 本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】
- 你可能需要根据不同的 url 渲染不同的【作者:唐霜】转载请注明出处:www.tangshuang.net文件,此时,你要多次调用 createL著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。iveReload 来实现多个中间件实例【作者:唐霜】【转载请注明来源】,当然,这个时候你要保证 matchUr本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。ls 的顺序是正确的。 【本文受版权保护】著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】
这就是简单的自刷新中间件了。本文作者:唐霜,转载请注明出处。
本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。【作者:唐霜】【原创内容,转载请注明出处】
