简体   繁体   中英

CSS inject not working with Gulp + Browsersync

I'm new in gulp, I used to work with grunt, and I'm having some troubles with gulp now.

The most important of them is the auto CSS inject, that isn't woking and after a lot of time I don't know why. Can anyone help me? And also give me some suggestions about my config? Thanks in advance!

'use strict';

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    autoprefixer = require('gulp-autoprefixer'),
    csso = require('gulp-csso'),
    jshint = require('gulp-jshint'),
    uglify = require('gulp-uglify'),
    imagemin = require('gulp-imagemin'),
    rename = require('gulp-rename'),
    clean = require('gulp-clean'),
    concat = require('gulp-concat'),
    notify = require('gulp-notify'),
    cache = require('gulp-cache'),
    sourcemaps = require('gulp-sourcemaps'),
    livereload = require('gulp-livereload'),
    lr = require('tiny-lr'),
    server = lr();


var browserSync = require('browser-sync').create();
var reload = browserSync.reload;

gulp.task('vendors', function() {
  return gulp.src('./assets/js/vendors/*.js')
    .pipe(concat('vendors.js'))
    .pipe(gulp.dest('./assets/js/'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest('./assets/js/'))
    .pipe(browserSync.stream())
    .pipe(notify({ message: 'Vendors task complete' }));
});

gulp.task('sass', function() {
  return gulp.src('./assets/sass/*.scss')
    .pipe(sourcemaps.init())
    .pipe(sass({ style: 'expanded', }))
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(gulp.dest('./assets/css/'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(csso())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./assets/css/'))
    .pipe(browserSync.stream())
    .pipe(notify({ message: 'Sass task complete' }));
});


gulp.task('serve',  function() {

    browserSync.init({
        proxy: "pageone.dev",
        files: "./assets/css/*.css",
        bsFiles: "./assets/css/*.css"
    });

    gulp.watch('./assets/sass/**/*.scss', ['sass']);
    gulp.watch('./assets/js/vendors/**.js', ['vendors']);
    gulp.watch('*.php', './assets/css/*.cs', './assets/js/*.js;').on('change', browserSync.reload);

});


gulp.task('default', ['serve', 'sass']);

Sourcemaps!

One of the annoying things that I spent too much time debugging is why browser-sync reloads the whole page instead of injecting CSS changes.

After diving into browser-sync files I found out that there default list for injecting files is set to:

injectFileTypes: ["css", "png", "jpg", "jpeg", "svg", "gif", "webp"],

The thing that might not be very apparent is that if any other file that is not on injectFileTypes gets changes the browser will reload. In my case the extra files that was changed were the sourcemap files *.css.map .

If you don't explicitly tell browsersync to ignore sourcemap files when changing or in the initial config the browser will always reload. There's two ways I believe to do this, one through the browsersync.stream method like the following:

  // Only stream the matching files. Ignore the rest.
  .pipe(browsersync.stream({match: '**/*.css'}));

Or on initializing browsersync like the following through the files option with excluding pattern to the sourcemaps files: ['!**/*.maps.css'] .

I like the first one since I am using browsersync with nodemon as a proxy so I don't really use the files argument and setup my own gulp watch statements.

One other way to do this is to update the injectFileTypes option when initializing browsersync, however, I am not sure if the CSS sourcemaps are injectable .

I hope this help someone having the same issue!

I found browserSync.stream very unreliable. I'd rather suggest a reload through a watch process:

Kill the line with browserSync in your Gulpfile:

gulp.task('sass', function() {
  return gulp.src('./assets/sass/*.scss')
    .pipe(sourcemaps.init())
    .pipe(sass({ style: 'expanded', }))
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(gulp.dest('./assets/css/'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(csso())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./assets/css/'))
    .pipe(notify({ message: 'Sass task complete' }));
});

And add the reload while watching:

gulp.task('serve',  function() {

   browserSync.init({
      proxy: "pageone.dev",
      files: "./assets/css/*.css",
      bsFiles: "./assets/css/*.css"
  });

  gulp.watch('./assets/sass/**/*.scss', ['sass']);
  gulp.watch('./assets/js/vendors/**.js', ['vendors']);
  gulp.watch('*.php').on('change', browserSync.reload);
  gulp.watch('./assets/js/*.js').on('change', browserSync.reload);
  gulp.watch('./assets/css/*.css').on('change', browserSync.reload);

});

Woah... I saw that you already did this. But there's a type on your CSS files, one "s" is missing:

 gulp.watch('*.php', './assets/css/*.cs', './assets/js/*.js;').on('change', browserSync.reload);

There's also a semi-colon at your JS files glob, and I'm not sure if you can pass multiple Globs here. Try using this lines:

  gulp.watch('*.php').on('change', browserSync.reload);
  gulp.watch('./assets/js/*.js').on('change', browserSync.reload);
  gulp.watch('./assets/css/*.css').on('change', browserSync.reload);

For me it was leaving wrong rel value in css link. I updated the href to point to css but rel was still stylesheet/less

The following actually works if you have reference to less.js and browserSync will update the page, but CSS will not be updated:

<link rel="stylesheet/less" type="text/css" href="css/styles.css" />

Changing rel to correct stylesheet fixes the problem

<link rel="stylesheet" type="text/css" href="css/styles.css" />

I was excited when I found this question, but then disappointment after all the previous answers were not what my issue WAS.

I finally tracked it down to the options object I was passing to browser-sync on start. That object was getting the path for the .less file that I setup a gulp.watch on that rebuilt the .css file for the site.

Tracked down that the path to the .less file started with "./src/client..." but browser-sync was getting the file as "src/client..." and although the paths are different and they point to the same file.

Browser-sync was seeing the .less file as changed and therefore refreshing as it's not in the injectable files list.

  • Be sure your paths match as pure STRINGS and not just point to the same file.

Hope this might help others who's issues aren't fixed by the above other options to check.

Watch out for @import to load css files in the page header. Drupal does this by default to avoid the css file limit in IE (among other reasons). For Drupal, you can use the Link CSS module or do some theming tricks.

Injection worked for me after making this change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM