【问题标题】:gulp-watch and LiveReload, reloads too earlygulp-watch 和 LiveReload,过早重新加载
【发布时间】:2017-01-10 09:35:14
【问题描述】:

我已经设置了 gulp-watch 和 LiveReload。它以某种方式起作用,但大多数时候都是错误的。感觉 LiveReload 比浏览器重新加载文件更快地发出重新加载事件。我可以这样解释:

  1. 我的 src 目录中的某些文件已更改
  2. 开始编译
  3. 当它仍在编译时,浏览器会重新加载页面
  4. 有时页面已经是新的且正确的。大多数时候它是旧的。有时它只是页面的一部分。
  5. 点击重新加载,一切正常。

我认为我在集成 gulp-watch 和 LiveReload 时犯了一些错误。你能帮我找一个吗?

这是我的 gulpfile.js:

var gulp = require('gulp');
var jade = require('gulp-jade');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
var connect = require('gulp-connect');
var favicons = require('gulp-favicons');
var ga = require('gulp-ga');
var postcss      = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var responsive = require('gulp-responsive');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var print = require('gulp-print');

gulp.task('default', ['jade', 'sass', 'js', 'connect', 'watch']);

gulp.task('jade', function() {
  gulp.src('./src/jade/*.jade')
    .pipe(jade())
    .pipe(ga({url: 'auto', uid: config.gaId, tag: 'body',sendPageView: true, minify: false, anonymizeIp: false}))
    .pipe(gulp.dest('./public/'));
});

gulp.task('sass', function () {
  gulp.src('./src/sass/style.scss')
    .pipe(sass({
      includePaths: [
        config.bowerDir + '/bootstrap/scss',
        config.bowerDir + '/font-awesome/scss'
      ],
      outputStyle: 'compressed'
    })
    .on('error', sass.logError))
    .pipe(postcss([ autoprefixer({ browsers: ['last 2 versions'] }) ]))
    .pipe(gulp.dest('./public/css'));
});

gulp.task('connect', function() {
  connect.server({
    root: 'public',
    livereload: true
  });
});

gulp.task('watch', function () {
  gulp.watch(['./src/jade/**/*.jade'], ['jade']);
  gulp.watch(['./src/sass/**/*.scss'], ['sass']);
  gulp.watch(['./src/js/**/*.js'], ['js']);
  watch(['./public/**/*.html', './public/**/*.css', './public/**/*.js']).pipe(connect.reload());
});

gulp.task('js', function () {
  return gulp.src([
    './node_modules/fontfaceobserver/fontfaceobserver.js',
    './bower_components/jquery/dist/jquery.min.js',
    './bower_components/bootstrap/js/dist/util.js',
    './bower_components/bootstrap/js/dist/collapse.js',
    './bower_components/picturefill/dist/picturefill.js',
    './src/js/modernizr.js',
    './src/js/js.js'
    ])
    .pipe(concat({ path: 'js.js'}))
    .pipe(uglify())
    .pipe(gulp.dest('./public/js'));
});

完整来源在这里https://gist.github.com/dandaka/3e342158763f9ccbd23305eecfd0b69c

谢谢!

【问题讨论】:

    标签: javascript gulp livereload


    【解决方案1】:

    .pipe(connect.reload()) 放在每个任务的末尾,例如 js

    return gulp.src([
        ...
        ])
        .pipe(concat({ path: 'js.js'}))
        .pipe(uglify())
        .pipe(gulp.dest('./public/js'))
        .pipe(connect.reload());
    

    因为现在当它在手表上时watch([...]).pipe(connect.reload()); 它会在编译开始但不一定完成时触发。

    【讨论】:

    • 工作正常。但是现在它重新加载了很多次。当所有编译完成后,有没有办法让它只重新加载一次?谢谢。
    • @dandaka 我不确定。我认为其他答案可能只重新加载一次。另外我建议使用浏览器同步进行实时重新加载而不是 gulp-connect,值得一试。
    • 这也不会可靠地工作。这取决于gulp.dest 必须处理多少文件,因为实际的复制过程将异步运行。所以你在这里有一个竞争条件,流可能已经在connect.reload(),而文件仍在被复制。
    【解决方案2】:

    除了@TheFallen 的建议之外,你最好的做法是创建一个单独的任务并将其放在监视任务的末尾。

    var gulp = require('gulp');
    var runSequence = require('run-sequence');
    
    gulp.task('reload', function() {
       connect.reload();
    });
    
    gulp.task('watch', function () {
      gulp.watch(['./src/jade/**/*.jade'], function() {
        runSequence('jade', 'reload');
      })
    
      gulp.watch(['./src/sass/**/*.scss'], function() {
        runSequence('sass', 'reload');
      });
    
      gulp.watch(['./src/js/**/*.js'], function() {
        runSequence('js', 'reload');
      });
    });
    

    UPD: 正如@Fencer 正确指出的那样,任务是同时执行的,这有时会导致在前一个任务完成之前重新加载页面的情况,我添加了run-sequence 包用法避免这个问题。

    【讨论】:

    • 这实际上是行不通的。不能保证例如jade 任务将在reload 开始之前完成。定义为监视事件运行的所有任务将同时运行。我试过了。
    • @Fencer 这确实是一个已经在StackOverflow's questions 中讨论过的问题,您可以找到可能的解决方案。
    • 是的,我知道这一点。但这并没有改变这样一个事实,即这个答案并不是问题本身的解决方案。我只是想向其他读者说明这一点,并提供一个可行的解决方案(见我的回答)。但是,对于 Gulp 3 使用 run-sequence 是一个很好的提示。如果您将其整合到您的答案中,那么它确实是一个合适的解决方案。
    • @Fencer,感谢您的帮助!我已经根据您的建议更新了我的答案!
    【解决方案3】:

    我最近遇到了同样的问题,这里提到的两种解决方案都不起作用,正如我在我的 cmets 中指出的那样。

    使用 Gulp 3,我能想到的唯一可行的解​​决方案如下(虽然我没有使用 gulp-connect,但实际的解决方案应该是通用的):

    gulp.task('jade', function() {
        var stream = gulp.src('./src/jade/*.jade')
            .pipe(jade())
            .pipe(ga({url: 'auto', uid: config.gaId, tag: 'body',sendPageView: true, minify: false, anonymizeIp: false}))
            .pipe(gulp.dest('./public/'))
            .on('end', function() {
                livereload.reload();
            });
    });
    
    ...
    
    gulp.task('watch', function () {
        livereload.listen();
        gulp.watch(['./src/jade/**/*.jade'], ['jade']);
        ...
    });
    

    我不知道 Gulp 内部是如何工作的,但on('end'...)似乎实际上是等到流的所有操作都完成了。

    使用 Gulp 4 可能会有一个看起来很像@Konstantin Azizov 的解决方案。

    gulp.task('reload', function() {
        connect.reload();
    });
    
    gulp.task('watch', function () {
        gulp.watch(['./src/jade/**/*.jade'], gulp.series('jade', 'reload'));
        ...
    });
    

    或者甚至只是:

    gulp.task('watch', function () {
        gulp.watch(['./src/jade/**/*.jade'], gulp.series('jade', function() {
            connect.reload();
        }));
        ...
    });
    

    请注意,我没有测试 Gulp 4 解决方案。我有点不愿意切换到版本 4,因为它还没有正式发布。不过还是很诱人的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-25
      • 2016-07-06
      • 2015-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多