why?
每次修改文件,为了看到修改后的效果,我们不得不每次F5刷新,有没有办法可以做到当文件修改时,浏览器能自动刷新呢?
这里的关键在于,connect 的配置中加入中间件工作,他的作用是在每个打开的页面中,执行lrSnippet 函数,这个函数的作用是什么呢?
chrome 中有插件:livereload .
what?
今天,我们通过grunt 的几个任务,实现修改本地文件,在浏览器中,自动刷新的功能。
我们要用到下面三个任务:
1 grunt-contrib-connect 为文件建立站点,实现通过浏览器访问文件的功能
2 grunt-regarde 监控哪些文件发生变化,当变化发生时,执行设定的任务
3 grunt-contrib-livereload 建立web socket 服务器,让页面同web socket 通行
通过上面的简单介绍,我们大致就能推理出,用grunt 任务怎么实现修改文件在浏览器中自动加载的:
通过connect 建立站点,利用regarde监控被修改的文件,触发livereload 的任务,livereload 通过web socket ,将与服务器相连接的页面都刷新一次
how?
这里理解的难点在于,怎样使connect 建立的站点文件,包含同livereload 建立的web socket 服务器通信的过程
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var folderMount = function folderMount(connect, point) {
return connect.static(path.resolve(point));
};
grunt.initConfig({
connect:{
server:{
options: {
port: 9001,
base:'./src',
middleware: function(connect, options) {
return [lrSnippet, folderMount(connect, options.base)]
}
}
}
}
})
var snippet = [
"<!-- livereload snippet -->",
"<script>document.write('<script src=\"http://'",
" + (location.host || 'localhost').split(':')[0]",
" + ':" + port + "/livereload.js?snipver=1\"><\\/script>')",
"</script>",
""
].join('\n');
上面是从lrSnippet 函数中copy出来的一个变量,他的作用是在返回的页面中,document.write 这个字符串,这样,就引入了livereload 的一个js。在这个js中,为页面建立了同web socket 服务器的web socket 功能。
这样,当服务器发现文件修改了,就能通过web socket 通知客户端,从而实现自动刷新功能
参考:http://gruntjs.com/getting-started#the-wrapper-function
http://gruntjs.com/configuring-tasks
https://github.com/yeoman/grunt-regarde
https://github.com/gruntjs/grunt-contrib-connect
https://github.com/gruntjs/grunt-contrib-livereload