Browsersync перезагружает страницу перед внедрением CSS

Я реализую сборку с использованием Gulp, Browsersync, Sass для CSS и Pug для HTML. Я также вставляю таблицы стилей <link>s в HTML после того, как стили и разметка скомпилированы.

Первоначальная сборка работает нормально, но у меня возникла проблема с отслеживанием изменений в файлах CSS и HTML с помощью Gulp. Что происходит сейчас, так это при изменении любого исходного файла (разметки или таблиц стилей), когда Browsersync перезагружает браузер, у меня остается страница без стиля, в которую не вставлены таблицы стилей <head>. Кажется, что перезагрузка Browsersync срабатывает после того, как pug (компиляция Pug в HTML) была завершена, но до завершения sass (компиляция Sass в CSS), и поэтому нечего вводить.

Главный вопрос: скажите, пожалуйста, как установить правильный порядок в Gulp.

Дополнительный вопрос: как это сделать так, чтобы при изменении разметки выполнялась полная перезагрузка страницы, но не выполнялась полная перезагрузка страницы при изменении таблицы стилей, а вместо этого вставлялись только CSS в <head>, как описано в эту статью и Gulp docs в разделе" SASS + CSS Injecting ".

Это мой код:

gulpfile.babel.js

import gulp from "gulp";

// Gulpfile is split across multiple files located in .gulp/.
// Importing them executes them and registers appropriate tasks.
import "./gulp/browser-sync.js";
import "./gulp/inject.js";
import "./gulp/markup.js";
import "./gulp/styles.js";
import "./gulp/watch.js";


// Build all the source files.
gulp.task("build", ["markup", "styles"]);

// Default task ran when `gulp` executed with no arguments.
gulp.task("default", ["build", "browser-sync"]);

gulp / browser-sync.js

import gulp from "gulp";
import browserSync from "browser-sync";

import paths from "./paths.js";


// Running a local server, which posts live updates to connected browsers when
// any of the source files change.
gulp.task("browser-sync", ["build", "watch"], () => {
  browserSync.init({
    server: {
      baseDir: paths.global.tmp
    }
  });
});

gulp / styles.js

import gulp from "gulp";
import sass from "gulp-sass";
import sassModuleImporter from "sass-module-importer";
import sourcemaps from "gulp-sourcemaps";
import browserSync from "browser-sync";
import del from "del";

import paths from "./paths.js";


gulp.task("styles", ["clean:styles", "sass", "inject"]);


// Compiles Sass stylesheets to CSS.
gulp.task("sass", ["clean:styles"], () => {
  const SASS_OPTIONS = {
    includePaths: paths.styles.src,
    importer: sassModuleImporter()
  };

  return gulp.src(paths.styles.srcMainGlob, { base: paths.styles.src })
             .pipe(sourcemaps.init())
             .pipe(sass(SASS_OPTIONS))
             .pipe(sourcemaps.write(paths.styles.maps))
             .pipe(gulp.dest(paths.styles.tmp))
             .pipe(browserSync.stream({ match: "**/*.css" }));
});


gulp.task("clean:styles", () => {
  let pathsToDel = [paths.styles.tmp, paths.styles.dist];
  return del(pathsToDel);
});


gulp.task("watch:styles", ["styles"], () => {
  gulp.watch(paths.styles.srcAllGlob, ["styles"]);
});

gulp / markup.js

import gulp from "gulp";
import pug from "gulp-pug";
import browserSync from "browser-sync";
import del from "del";

import paths from "./paths.js";


gulp.task("markup", ["clean:markup", "pug", "inject"]);


// Compile Pug templates to HTML
gulp.task("pug", ["clean:markup"], () => {
  return gulp.src(paths.markup.srcMainGlob)
             .pipe(pug())
             .pipe(gulp.dest(paths.markup.tmp))
             .pipe(browserSync.stream());
});


gulp.task("clean:markup", () => {
  let pathsToDel = [paths.markup.tmp, paths.markup.dist];
  return del(pathsToDel);
});


gulp.task("watch:markup", ["markup"], () => {
  gulp.watch(paths.markup.srcAllGlob, ["markup"]);
});

gulp / inject.js

import gulp from "gulp";
import inject from "gulp-inject";

import paths from "./paths.js";


gulp.task("inject", ["inject:styles"]);


// Inject generated stylesheets into HTML files.
gulp.task("inject:styles", ["pug", "sass"], () => {
  let sources = gulp.src(paths.styles.tmpGlob, { read: false });

  return gulp.src(paths.markup.tmpGlob)
             .pipe(inject(sources, { relative: true }))
             .pipe(gulp.dest(paths.markup.tmp));
});

gulp / watch.js

import gulp from "gulp";


// Watching for all the changes in source files.
gulp.task("watch", ["watch:markup", "watch:styles"]);

А вот вывод консоли после запуска gulp и внесения изменений в один из исходных файлов Sass:

[BS] Access URLs:
 --------------------------------------
       Local: http://localhost:3000
    External: http://192.168.88.32:3000
 --------------------------------------
          UI: http://localhost:3001
 UI External: http://192.168.88.32:3001
 --------------------------------------
[BS] Serving files from: .tmp/
[12:00:30] Starting 'clean:styles'...
[12:00:30] Starting 'clean:markup'...
[12:00:30] Finished 'clean:markup' after 3.12 ms
[12:00:30] Starting 'pug'...
[12:00:30] Finished 'clean:styles' after 8.61 ms
[12:00:30] Starting 'sass'...
[BS] Reloading Browsers...
[BS] 1 file changed (index.html)
[12:00:30] Finished 'pug' after 72 ms
[BS] 1 file changed (main.css)
[12:00:30] Finished 'sass' after 144 ms
[12:00:30] Starting 'inject:styles'...
[12:00:30] gulp-inject 1 files into index.html.
[12:00:30] Finished 'inject:styles' after 9.67 ms
[12:00:30] Starting 'inject'...
[12:00:30] Finished 'inject' after 2.99 μs
[12:00:30] Starting 'styles'...
[12:00:30] Finished 'styles' after 2.47 μs

person Robert Kusznier    schedule 04.04.2017    source источник


Ответы (1)


Первое, что нужно сделать, это добавить browserSync в вашу inject:styles задачу, иначе она не будет перезагружена после того, как ссылки стиля были введены.

// Inject generated stylesheets into HTML files.
gulp.task("inject:styles", ["pug", "sass"], () => {
  let sources = gulp.src(paths.styles.tmpGlob, { read: false });

  return gulp.src(paths.markup.tmpGlob)
         .pipe(inject(sources, { relative: true }))
         .pipe(gulp.dest(paths.markup.tmp))
         .pipe(browserSync.stream());
});
person lofihelsinki    schedule 05.04.2017
comment
Истинный. Я даже вчера сам добавил это. Думаю, это ответ на мой главный вопрос. - person Robert Kusznier; 05.04.2017
comment
Что касается вашего дополнительного вопроса, я думаю, что browserSync должен обрабатывать инъекцию автоматически, когда вы перенаправляете его на browserSync.stream(). Он не должен перезагружать всю страницу? - person lofihelsinki; 05.04.2017
comment
По моему опыту browserSync.stream() отлично работает с инъекцией только тогда, когда вы передаете ему файлы Sass внутри sass задачи. Итак, я закончил тем, что выполнял browserSync.stream() как в sass, так и в inject:styles задачах, при этом watch:styles запускал iinject:styles только при добавлении или удалении какого-либо файла и sass в противном случае (когда файл был изменен). - person Robert Kusznier; 05.04.2017