请想象这样一个场面:你开着两个显示器,一边是IDE里的代码,另一边是浏览器里的你正在开发的应用。此时桌上还放着你的手机,手机里也是这个开发中的应用。然后,你新写了一小段代码,按下了ctrl+s保存。紧接着,你的手机和另一个显示器里的应用,就变成了更新后的效果。你可以马上检查效果是否和你预想的一致,甚至都不需要动一下鼠标...

想起来还不错?嗯,这只是简单地省略掉那个开发过程中会按好多遍的F5刷新。

自动刷新

“自动刷新”并不是新的概念,但对关注“可见”的预览效果的前端开发者来说,它非常好用,可以节约很多时间。

我也不是现在才知道这个概念。在这之前,我一直在用[LiveReload][],它是一个名字上更明显地写着“自动刷新”的工具。LiveReload主要搭配浏览器插件使用,是很棒的自动刷新工具。

不过,现在我要介绍的是[BrowserSync][]。你会在接下来的内容里看到,它是一个更新、更方便的开发工具。

BrowserSync

LiveReload有所不足的地方是,需要搭配浏览器插件。但是,插件是取决于浏览器的,Chrome和Firefox都有可用插件(见[这页][]),但IE,或者我手机上的浏览器,就不能这样了。这时候只能手工向页面里添加一段<script>代码(其实插件也是做了这件事),而且还要记得结束后再手工移除。

BrowserSync的一般用法则不需要浏览器插件,也不用手工添加代码(尽管也提供那样的用法)。一句控制台的命令之后,无论是在手机里还是电脑,无论用多少个浏览器(经测试,IE8+及其它),都可以拥有自动刷新的功能。

BrowserSync是怎么做到的?请看它的安装及使用。

安装及使用

安装Node[]安装BrowserSync:

npm install -g browser-sync

然后,就可以开始使用了。打开控制台进入项目所在的目录,然后输入像这样的命令:

browser-sync start --server --files "css/*.css"

这个命令用于纯静态站点,也就是仅一些.html文件的情况。后面的--files "css/*.css",是指监听css目录中的后缀名为.css的文件。请注意这个命令里的start --server,这其实是BrowserSync自己启动了一个小型服务器。

如果是动态站点,则使用代理模式。例如PHP站点,已经建立了一个本地服务器如http://localhost:8080,此时会是这样的命令:

browser-sync start --proxy "localhost:8080" --files "css/*.css"

BrowserSync会提供一个新地址(如未被占用的话,http://localhost:3000)用于访问。

好了,为什么BrowserSync不需要浏览器插件?因为它使用了服务器的形式(直接或代理)来处理项目文件。默认情况下,访问它的服务器上的网页,可以看到这样的提示签:

这说明当前浏览的网页已连接到BrowserSync。查看一下源码,会发现它们都被添加了与BrowserSync有关的一段<script>代码,就像LiveReload浏览器插件做的那样。这些代码会在浏览器和BrowserSync的服务器之间建立web socket连接,一旦有监听的文件发生变化,BrowserSync会通知浏览器。

如果发生变化的文件是css,BrowserSync不会刷新整页,而是直接重新请求这个css文件,并更新到当前页中,效果像这样:

显然,这感觉更加快捷。如果你正在开发的是一个单页应用([SPA][]),刷新整页会回到初始视图,而你又需要修改后面的某一个视图时,这一功能尤其有用。

文件匹配

从BrowserSync的命令来看,很重要的一点就是通过--files指定需要监听的文件。有关这里的文件匹配模式(称为glob)的详情,请参考[isaacs's minimatch][]。

经过我自己的尝试,如果简单只是想要监听整个项目,可以写成这样:

browser-sync start --server  --files "**"

此时,BrowserSync仍然会正确地判断文件变化是否是css。

加入到Gulp使用

[Gulp][]是现在流行的自动化工具,但BrowserSync并没有Gulp插件版,因为并不需要。BrowserSync有自己独立的API,将它注册为gulp的一个task即可。下面是一段gulpfile.js的示例:

var gulp = require('gulp');
var browserSync = require('browser-sync');

gulp.task('browser-sync', function() {
    browserSync({
        files: "**",
        server: {
            baseDir: "./"
        }
    });
});

gulp.task('default', ["browser-sync"]);

这时候运行gulp将等同于前文的browser-sync start --server --files "**"。更多的用法示例请查看[gulp-browser-sync][]。

完整选项

到此为止,介绍的都是BrowserSync的基本用法。在控制台里尝试只输入:

browser-sync

你会看到BrowserSync完整的控制台命令指南。其中可以看到有这个命令:

browser-sync init

运行它,将在当前目录生成一个配置文件bs-config.js

参照[官方文档][]修改这个文件,然后运行

browser-sync start --config bs-config .js

就将以bs-config.js的完整配置信息运行BrowserSync。

不只是自动刷新

BrowserSync并不只是一个自动刷新工具,它还有许多其他功能。默认配置下,BrowserSync会在多个浏览器中同步滚动条位置,表单行为和点击事件。例如,表单行为的情形像这样:

我觉得这是很酷的功能!想象一下桌上摆很多个不同屏幕尺寸的手机来测试的情景,你操作一个,就会带动其他的一起!当然,这些功能还可以在不需要的时候关闭。

UI界面及其他

下面是一个BrowserSync的控制台输出示例:

可以看到还有一个叫做UI的一个地址,它是BrowserSync提供的一个简易控制面板。BrowserSync最常用的几个配置选项,都可以在这个面板里调整。

在面板里面你还会发现那个经典的远程调试工具[weinre][]也在这:

BrowserSync目前已知的一点问题

前文提到,如果发生变化的文件是css,BrowserSync会以无刷新方式来更新,这是一个很棒的效果。如果使用scss、less等预编译器,将监听设置为编译后的css文件即可。

但是,Web应用框架Rails[]。

一个可行的解决方法是用其他工具替代Rails的Asset Pipeline。但在这里,我推荐另一个解决方案:使用LiveReload(LiveReload你还是有点水平的!)。经测试,LiveReload在Rails中也可以处理好css的快捷更新。关于LiveReload做到这一点的原理,你可以阅读[Lightning-Fast Sass Reloading in Rails][]。

也期待BrowserSync可以在未来解决这个问题。

结语

想要在开发中更流畅,更快捷?请尝试BrowserSync!节约一点时间,你也许就可以做到更多。

(重新编辑自我的博客,原文地址:http://acgtofe.com/posts/2015/03/more-fluent-with-browsersync

你可能感兴趣的文章

27 条评论
n͛i͛g͛h͛t͛i͛r͛e͛ · 2015年03月22日

关于 Rails 的问题,你可以把 stream based reload 关掉,这样 css 文件(sass)变化的时候就会和其他文件一样真正刷新。

回复

苏生不惑 · 2015年05月24日

windows安装出错

MSBUILD : error MSB3428: 未能加载 Visual C++ 组件“VCBuild.exe”。要解决此问题,
1) 安装 .NET Fram
ework 2.0 SDK;2) 安装 Microsoft Visual Studio 2005;或 3) 如果将该组件安装到了
其他位置,请将其位置添加到系统
路径中。 [d:\nodejs\node_modules\browser-sync\node_modules\socket.io\node_module
s\s
ocket.io-client\node_modules\engine.io-client\node_modules\ws\build\binding.sln
]
MSBUILD : error MSB3428: 未能加载 Visual C++ 组件“VCBuild.exe”。要解决此问题,
1) 安装 .NET Fram
ework 2.0 SDK;2) 安装 Microsoft Visual Studio 2005;或 3) 如果将该组件安装到了
其他位置,请将其位置添加到系统
路径中。 [d:\nodejs\node_modules\browser-sync\node_modules\socket.io\node_module
s\s
ocket.io-client\node_modules\engine.io-client\node_modules\ws\build\binding.sln
]

回复

EdwardUp 作者 · 2015年05月25日

请参考 http://www.browsersync.io/docs/#windows-users ,安装Visual Studio.

回复

mqliutie · 2015年06月19日

Hello,我是在gulp中使用的.在'gulpfile.js'中我这样配置的 :

JavaScriptvar gulp = require('gulp'),
    browserSync = require('browser-sync').create(),
    less = require("gulp-less");
gulp.task('less', function () {
    return gulp.src('less/*.less')
        .pipe(less())
        .pipe(gulp.dest('css'));
});

gulp.task('less-watch', ['less'], browserSync.reload);

gulp.task('serve', ['less'], function () {

    browserSync.init({
        server: {
            baseDir: "./"
        }
    });
    gulp.watch("less/*.less", ['less-watch']);
});

但是有一个问题,我进到./app/index.html 引用的是 ./css/index.css 当我修改less文件时,默认有的,比如color:blue我修改成了red,OK 立刻刷新了,但是当我新加属性 比如加一个border,加不进去,而且我在修改color属性,也没用了,博主知道怎么解决吗?

回复

EdwardUp 作者 · 2015年06月23日

试了一下确实如此。 我也碰到过类似的问题(我是修改js文件发现不刷新)。 解决方法是,

gulp.task('less-watch', ['less'], browserSync.reload);

修改为

gulp.task('less-watch', ['less'], function(){
    browserSync.reload();
});

对于html以外的如css、js等资源文件,都建议用这样的写法。

回复

mqliutie · 2015年06月24日

我现在配置是按照官方的配置的 如下:

jsvar   gulp = require("gulp"),
    less = require("gulp-less"),
    browserSync = require("browser-sync"),
    path = {
        HTML : "Wechat/public/html/weShop/*.html",
        LESS : "Wechat/public/style/less/*.less",
        CSS : "Wechat/public/style/css"
    };

gulp.task("serve", ["less"], function() {
    browserSync.init({
        server : "./"
    });

    gulp.watch(path.LESS, ["less"]);
    gulp.watch(path.HTML).on("change", function() {
        browserSync.reload;
    })
});

gulp.task("less", function() {
    gulp.src(path.LESS)
        .pipe(less())
        .pipe(gulp.dest(path.CSS))
        .pipe(browserSync.stream());
})

因为改动css 我主要是在less修改,现在修改,添加 删除属性都没有问题.但是我看到这句

jsgulp.watch(path.HTML).on("change", function() {
        browserSync.reload;
    })
检测的明明是html文件,为什么我修改html文件的时候,比如新加某个div的时候却不实时更新,请问博主修改html文件会自动刷新么

回复

mqliutie · 2015年06月24日

    • 为什么评论markdown这么不友好

回复

EdwardUp 作者 · 2015年06月25日

写法有误?请修改为(reload()而不是reload才表示函数调用)。

gulp.watch(path.HTML).on("change", function() {
    browserSync.reload();
});

回复

mqliutie · 2015年06月26日

没影响的- -,这个插件应该只对css起作用吧,如果你修改JS或者直接修改html内容也自动刷新的话如果你不介意可以把配置更新在博文里,谢谢

回复

mqliutie · 2015年06月26日

http://segmentfault.com/a/1190000002919912 我刚才写的,可以对js和html进行自动刷新了

回复

EdwardUp 作者 · 2015年06月26日

嗯搞定就好。我参考的是官方的 http://www.browsersync.io/docs/gulp/

回复

我要7西瓜 · 2015年10月30日

请问使用browser-sync,文件结构是什么样子的呢,比如说init里设置server:'./app',执行gulp后浏览器会立即打开 localhost:3000,请问这个地址对应的是哪个文件~

回复

EdwardUp 作者 · 2015年11月02日

配置文件bs-config.js里写server: {baseDir: "app"} 的话,参照官方文档,如果你的项目目录里新建了一个叫app的目录,那么 localhost:3000 就对应到你的app目录,默认取app/index.html这个文件(如果存在)。 如果 localhost:3000/black/white.html 就对应 app/black/white.html 这个文件。

回复

我要7西瓜 · 2015年11月15日

可以了~~谢谢你~

回复

颜海镜 · 2015年12月26日

赞赞赞赞

回复

ChristianShuai · 2016年01月13日

您好,我现在遇到一点问题,就是添加新的html文件浏览器 不会自动打开,这个该怎么解决?还有就是怎么设置默认打开所有html文件呢?

回复

EdwardUp 作者 · 2016年01月14日

哦?我理解的BrowserSync并没有自动打开html的功能呢,它是自动刷新。在命令行里启动BrowserSync后,具体要看打开自己的某一个html文件,都需要自己去手动做,也就是输html的对应地址。

回复

ChristianShuai · 2016年01月15日

你好,我现在的问题是我每次更改css后必须要等到下次刷新才能看到生效,我感觉是我的处理流程有一点问题,您能帮我看一下吗?我企鹅是578767687,谢谢

回复

beka · 2016年11月12日

请问sass + php 要怎么做?

gulp.task ('sass', function () {
    return gulp.src (CSS)
                .pipe (sass ())
                .pipe (gulp.dest (DEST + '/css'))
                .pipe (reload ({stream :true}));
});

gulp.task ('browser-sync',['sass'], function () {
    browserSync.init ({
        proxy : options.proxy,//传递过来的参数:"localhost:80/目录名"
        files : options.files,//要监听的文件 "**"
        // server : "./"
    });
    gulp.watch ("css/*.scss", ['sass']);
    gulp.watch ("./*.php").on ('change', reload);

在更新php文件的时候会自动,但更新scss时就不会自动刷新。
我用静态服务器 + HTML是可以的, 动态代理是不行吗?
还有我看大家都是在html里用sass,前端界面不用用php来写吗??

回复

EdwardUp 作者 · 2016年11月14日

动态代理当然可以。sass不会自动刷新可能是你配置有误,比如browserSync.init()可能不再需要配置files属性(你已经用gulp来监听了),或检测路径没有正确包含sass的目录。browserSync的设计就是,纯静态html用browserSync自己的server,有自己的server的话(php等)则用proxy

回复

载入中...
EdwardUp EdwardUp

4.9k 声望

发布于专栏

庭院茶

天津大学毕业生,从事前端开发。爱好动画,也喜欢做设计,现在画师学习中。个人博客 http://acgtofe.com

53 人关注