I'm attempting to use browser-sync with Gulp 4 and the new bs .stream() syntax, but bs is not preserving state and does a full refresh. Have you folks created a recipe / best practice for gulp v4 yet, so I can compare notes. Thanks for this awesome tool.
I guess some code would help.
The styles:dev task:
gulp.task('styles:dev', function() {
return gulp.src(config.src)
.pipe(sourcemaps.init())
.pipe(postcss(config.postcss.dev))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(config.dest.dev))
.pipe(browserSync.stream());
});
The browserSync task:
gulp.task('browserSync', function(cb) {
browserSync.init(config, cb);
});
The watch task:
gulp.task('watch:styles', function() {
return gulp.watch(config.paths.css,
gulp.series('styles:dev'));
});
gulp.task('watch', gulp.parallel('watch:styles'));
Finally, the default task:
gulp.task('default',
gulp.series('clean:dev',
gulp.parallel('copy:dev', 'styles:dev'), 'browserSync', 'watch')
);
Thanks in advance.
Fixed. Here's where I went wrong:
The browser-sync constructor takes an options object, which can include a files array. Most of the tutorials I've read, including the gulpfile for Google's very own Web Starter Kit, do not include this. As it turns out, this is required for style injection to preserve state.
Furthermore, do not pass .stream() or .reload() as the final pipe in your styles task. It is not needed, and will short circuit style injection, forcing a full refresh.
Finally, the browserSync process must not be terminated, and watch and browserSync tasks must execute in parallel in order for live style injection to take place.
Hope this helps anybody facing this issue.
@JamesJosephFinn would you show the resulting gulpfile?
@iliakan sure:
var config = {
server: {
baseDir: './dev/'
},
files: [
'./dev/*.css'
],
browser: 'google chrome canary',
notify: false
};
gulp.task('browserSync', function() {
browserSync.init(config);
});
and then a separate file for css task setup:
var config = {
src: './src/css/styles.css',
dest: {
dev: './dev/'
}
};
gulp.task('css:dev', function() {
return gulp
.src(config.src)
.pipe(foo()) // whatever you're into
.pipe(gulp.dest(config.dest.dev));
});
watching is a joy in gulp4:
var config = {
paths: {
css: './src/css/**/*'
}
};
gulp.task('watch:css', function() {
return gulp.watch(config.paths.css,
gulp.series('css:dev'));
});
gulp.task('watch', gulp.parallel('watch:css'));
and then the default task... I've only shown css related stuff above, to keep this a simple illustration of live style injection using browser-sync and gulp4:
gulp.task('default',
gulp.series(
'clean:dev',
gulp.parallel(
'copy:dev', 'html:dev', 'css:dev',
'js:dev', 'svgSymbol:dev', 'svg:dev'
),
gulp.parallel('watch', 'browserSync')
)
);
NB, also, the important difference in the default task: the browserSync process must not be terminated, and watch and browserSync must execute in parallel.
@JamesJosephFinn, do you mind explaining how you're splitting out your tasks into multiple files? Using gulp-hub?
I use an npm module called require-dir which creates an object out of the contents of the directory you pass in. Each file in the directory will be assigned a key, and the value will be the file contents. In your gulpfile.js:
// Node module to require an entire directory
var requireDir = require('require-dir');
// Pull in all task files from the /gulp directory
requireDir('./gulp');
The keys will be created by file name in alphabetical order. This can create issues, as I'm sure you can imagine. Gulp v. 4 to the rescue again with a new feature they've dubbed _forward references_. I've never used the API, nor do I know how, but it is certainly useful.
Helped me! Thanks!
馃憤
@JamesJosephFinn Can I download scripts without reloading the page?
@rtxrulez, unsure what you mean by this. Care to explain a bit more about your use case?
Tried to follow @JamesJosephFinn, but failed.
The only way i got it to work was add a .pipe(browserSync.stream()) to compass task. Without it the compass task would succeed, but no injection would take place. Now at least i have a browser refresh.
See my gulp for details:
gulpfile_1.zip
With the above configuration, should the page be automatically refreshing when changes are detected? For me it got watch and browserSync running in parallel, but no automatic refresh when code is edited. There doesn't seem to be anywhere in the config where we are telling browserSync when to refresh, so perhaps this was not the intention (others here seem to be expecting it too).
Update: The way I got reloading to work (for anyone landing here in the future).
gulp.task('reload', function(done) {
browserSync.reload();
done();
});
gulp.task('watch:dist', function() {
return gulp.watch('./dist/**/*',
gulp.series('reload'));
});
gulp.task('watch', gulp.parallel('watch:css', 'watch:dist'));
Most helpful comment
@iliakan sure:
and then a separate file for css task setup:
watching is a joy in gulp4:
and then the default task... I've only shown css related stuff above, to keep this a simple illustration of live style injection using browser-sync and gulp4: