Browsersync监听文件变更后无法触发页面自动刷新问题
问题背景
运行环境
- 主机系统:MacOS
- 主机侧已安装Browsersync,本地部署了Mark Shust提供的Docker版Magento环境
- Magento的.less主题文件存放在
app/design/frontend目录下,操作时已将该目录设为命令行当前工作目录
操作与现象
主机侧执行如下命令启动Browsersync:
browser-sync start --host "domain.test" --proxy "https://domain.test" --files "**/*.less" --https
命令执行后输出如下:
[Browsersync] Proxying: https://domain.test [Browsersync] Access URLs: -------------------------------------- Local: https://localhost:3000 External: https://domain.test:3000 -------------------------------------- UI: http://localhost:3002 UI External: http://localhost:3002 -------------------------------------- [Browsersync] Watching files...
运行后出现的现象:
- 直接访问
https://domain.test站点运行无异常 - 访问
http://localhost:3002的Browsersync管理UI时,显示当前无任何连接,但命令行终端会输出提示:[Browsersync] Reloading Browsers... - 修改.less文件后,站点最终能加载到修改后的样式内容,但必须手动刷新页面才能看到变更,不会自动触发页面刷新
- 参考Browsersync官方文档的Grunt配置示例,使用Magento标准Grunt配置文件进行配置后,问题仍然存在,配置代码如下:
module.exports = function (grunt) { 'use strict'; grunt.initConfig({ watch: { files: 'app/design/**/*.less', tasks: ['less'] }, browserSync: { dev: { bsFiles: { src : [ 'app/design/**/*.css' ] }, options: { watchTask: true, server: './' } } } }); // load npm tasks grunt.loadNpmTasks('grunt-contrib-sass'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-browser-sync'); // define default task grunt.registerTask('default', ['browserSync', 'watch']); var _ = require('underscore'), path = require('path'), filesRouter = require('./dev/tools/grunt/tools/files-router'), configDir = './dev/tools/grunt/configs', tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'), themes; filesRouter.set('themes', 'dev/tools/grunt/configs/themes'); themes = filesRouter.get('themes'); tasks = _.map(tasks, function (task) { return task.replace('.js', ''); }); tasks.push('time-grunt'); tasks.forEach(function (task) { require(task)(grunt); }); require('load-grunt-config')(grunt, { configPath: path.join(__dirname, configDir), init: true, jitGrunt: { staticMappings: { usebanner: 'grunt-banner' } } }); _.each({ /** * Assembling tasks. * ToDo: define default tasks. */ default: function () { grunt.log.subhead('I\'m default task and at the moment I\'m empty, sorry :/'); }, /** * Production preparation task. */ prod: function (component) { var tasks = [ 'less', 'cssmin', 'usebanner' ].map(function (task) { return task + ':' + component; }); if (typeof component === 'undefined') { grunt.log.subhead('Tip: Please make sure that u specify prod subtask. By default prod task do nothing'); } else { grunt.task.run(tasks); } }, /** * Refresh themes. */ refresh: function () { var tasks = [ 'clean', 'exec:all' ]; _.each(themes, function (theme, name) { tasks.push('less:' + name); }); grunt.task.run(tasks); }, /** * Documentation */ documentation: [ 'replace:documentation', 'less:documentation', 'styledocco:documentation', 'usebanner:documentationCss', 'usebanner:documentationLess', 'usebanner:documentationHtml', 'clean:var', 'clean:pub' ], 'legacy-build': [ 'mage-minify:legacy' ], spec: function (theme) { var runner = require('./dev/tests/js/jasmine/spec_runner'); runner.init(grunt, { theme: theme }); grunt.task.run(runner.getTasks()); } }, function (task, name) { grunt.registerTask(name, task); });};
待解答疑问
- 不运行GruntJS的情况下,Browsersync是否可以正常实现自动刷新功能?
- 当前场景下页面自动刷新无法被触发的原因是什么?
解答
关于第一个问题
完全可以。Browsersync本身是独立的文件监听、反向代理、自动刷新工具,核心功能不需要依赖Grunt、Gulp这类构建任务运行器就能正常使用。Grunt相关的配置只是官方提供的集成封装,作用是方便把Browsersync和less编译、资源压缩、代码校验等其他构建流程串起来自动执行,不是Browsersync运行的必选项。
自动刷新失效的核心原因
本质是Browsersync的客户端通信脚本根本没有注入到你访问的页面里,服务端就算监听到文件变化,也没法给浏览器发刷新指令,具体问题点有三个:
- 访问地址错误。Browsersync的自动刷新逻辑,是在反向代理返回HTML响应时,自动注入一段websocket客户端脚本,靠这个脚本和本地Browsersync服务保持长连接、接收刷新/样式注入指令。你现在直接访问源站地址
https://domain.test,根本没走Browsersync的代理通道,页面里自然没有这段通信脚本,Browsersync后台UI显示无连接、收不到刷新指令都是必然结果,正确的访问地址应该是Browsersync输出的代理地址https://localhost:3000或者映射后的https://domain.test:3000。 - 文件监听配置不符合Magento的运行逻辑。你现在直接监听源目录下的
.less文件,Magento并不会在你修改less文件后实时编译成浏览器可识别的css文件,需要走自带的静态资源编译流程才会把最终css输出到pub/static目录下。你直接监听less文件触发刷新时,新的样式还没编译完成,就算触发刷新也看不到最新效果,应该监听编译完成后的css文件路径。 - 现有Grunt配置存在冲突。配置里写了
server: './'参数,这个参数是用来让Browsersync直接托管本地静态文件的,和你需要的反向代理Magento站点的模式完全冲突;而且配置里监听的文件路径是app/design/**/*.css,这个路径下只会存less源文件,不会生成编译后的css,根本触发不了对应的刷新动作。
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

