BrowserSync / browser-sync

Keep multiple browsers & devices in sync when building websites. https://browsersync.io
https://discord.gg/2d2xUThp
Apache License 2.0
12.19k stars 757 forks source link

Browser Sync not injecting/updating styles #955

Open paperrobots opened 8 years ago

paperrobots commented 8 years ago

I'm using a similar gulpfile to the one on the website. I'm just compiling sass and reloading the styles. The site loads just fine at the BS localhost and IP address, works as it should. Sass compiles but styles don't update on the sites. Any ideas?

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

    gulp.task('serve', ['sass'], function() {

    browserSync.init({
        proxy: "rwr.dev"
    });

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

     // Compile sass into CSS & auto-inject into browsers
     gulp.task('sass', function() {
    return gulp.src("sass/*.scss")
        .pipe(sass())
        .pipe(gulp.dest("css"))
        .pipe(browserSync.stream());
    });

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

It's a wordpress site running in MAMP if that matters. I have gulp and browser-sync setup inside my theme directory.

renestalder commented 8 years ago

Struggling with the same. Maybe also related #943

pruhstal commented 8 years ago

Same here, but only after upgrading to El Capitan.

Believe that's the likely culprit.

EDIT: It's a permissions issue with El Capitan. For your current user run this:

sudo chown -R $(whoami):admin /usr/local

and it should now have the write access it needs to the filesystem to make the updates.

renestalder commented 8 years ago

Why does it need write access to the file system? My node and npm is installed via homebrew so it doesn't need sudo.

paperrobots commented 8 years ago

One change I made that worked was changing the stream call. It's not in the docs, someone on reddit mentioned it to me.

 .pipe(browserSync.stream());

becomes

 .pipe(browserSync.reload({ stream: true}));

Here's my final file I got working if anyone is curious:

    var gulp = require('gulp'),
    plumber = require('gulp-plumber'),
    rename = require('gulp-rename');
    var autoprefixer = require('gulp-autoprefixer');
    var minifycss = require('gulp-minify-css');
    var sourcemaps = require('gulp-sourcemaps');
    var sass = require('gulp-sass');
    var browserSync = require('browser-sync');

    gulp.task('serve', ['sass'], function() {

      browserSync.init({
        proxy: "rwr.dev"
      });

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

    // Compile sass into CSS & auto-inject into browsers
    gulp.task('sass', function() {
      gulp.src(['sass/*.scss'])

      .pipe(plumber({
          errorHandler: function(error) {
            console.log(error.message);
            this.emit('end');
          }
        }))
        .pipe(sourcemaps.init())
        .pipe(sass())
        .pipe(autoprefixer('last 2 versions'))
        .pipe(gulp.dest('css'))
        .pipe(rename({
          suffix: '.min'
        }))
        .pipe(minifycss())
        .pipe(sourcemaps.write('./')) //.pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('css'))
        .pipe(browserSync.reload({
          stream: true
        }));
    });

    gulp.task('default', ['serve']);
renestalder commented 8 years ago

I think browserSync.reload({ stream: true}) is deprecated.

paperrobots commented 8 years ago

I made those permissions fixes for El Capitan above and now this code works:

.pipe(browserSync.stream());

However, it injects the CSS then does a hard refresh anyways. Any way to stop that?

kaumac commented 8 years ago

Same issue here, I compile the sass files and trigger the BS reload but the site doesn't get the styles and I need to manually refresh the page to see the changes.

kaumac commented 8 years ago

stylebreaking the usual compiled style is the screen on the left, and once I save and compile a sass file, browsersync reloads, but the style doesn't, and I need to manually refresh the page to see the changes.

this is my gulpfile:

'use strict';

var gulp        = require('gulp'),
  eslint        = require('gulp-eslint'),
  modRewrite    = require('connect-modrewrite'),
  browserSync   = require('browser-sync').create(),
  del           = require('del'),
  concat        = require('gulp-concat'),
  uglify        = require('gulp-uglify'),
  rename        = require('gulp-rename'),
  ngAnnotate    = require('gulp-ng-annotate'),
  bowerFiles    = require('main-bower-files'),
  cleanCss      = require('gulp-cleancss'),
  sass          = require('gulp-sass'),
  neat          = require('node-neat').includePaths,
  autoprefixer  = require('gulp-autoprefixer'),
  runSequence   = require('run-sequence'),
  inject        = require('gulp-inject'),
  env           = process.env.NODE_ENV || 'development',
  isDevelopment = env === 'development';

// ======================================================================================================
// Development tasks
// ======================================================================================================

// Clean dist build directory
gulp.task('clean-dev', function () {
  del(['./tmp']);
});

// Build custom and third party Sass/Css
gulp.task('css-dev', function () {
  return gulp.src('./app/scss/application.scss')
    .pipe(sass({
      errLogToConsole: true,
      // includePaths: ['bower_components/susy/sass']
      includePaths: ['styles'].concat(neat)
    }))
    .pipe(autoprefixer({
      cascade: false
    }))
    .pipe(gulp.dest('./.tmp/'))
    .pipe(browserSync.reload({
      stream: true
    }));
});

// Run ESLint
gulp.task('js-lint', function () {
  return gulp.src(['./www/js/**/*.js'])
    .pipe(eslint())
    .pipe(eslint.format());
});

// Inject dev assets into HTML
gulp.task('inject-dev-assets', function () {
  var bowerList = bowerFiles({checkExistence: true});
  var assetList = [
    './.tmp/*.css',
    './.tmp/*.js',
    './app/js/application.js',
    './app/js/controllers/**/*.js',
    './app/js/services/**/*.js',
    './app/js/directives/**/*.js'
  ]
  var injectList = bowerList.concat(assetList);

  return gulp.src('./app/index.html')
  .pipe(inject(gulp.src(injectList, {read: false})))
  .pipe(gulp.dest('./.tmp'));
});

// Watch task for development
gulp.task('watch', function () {
  gulp.watch(['./app/js/**/*.js'], ['js-lint']);
  gulp.watch(['./app/scss/**/*.scss'], ['css-dev']);
  gulp.watch('bower.json', ['inject-dev-assets']);

  gulp.watch(['./app/js/**/*.js'], browserSync.reload);
  browserSync.watch(['./app/views/**/*.html'], browserSync.reload);
  browserSync.watch(['./dist/src/**/*.css'], function (event, file) {
    if (event === "change" || event === "add") {
      browserSync.reload();
    }
  });
});

// Dev server
gulp.task('browser-sync', function () {
  browserSync.init({
    port: 3000,
    ui: {
      port: 5000
    },
    server: {
      baseDir: '.tmp',
      routes: {
        '/bower_components': 'bower_components',
        '/app/js': 'app/js',
        '/.tmp': '.tmp',
        '/views': 'app/views'
      },
      middleware: [
        modRewrite([  // for HTML5 mode support
          '!\\.\\w+$ /index.html [L]'
        ])
      ]
    }
  });
});

// ======================================================================================================
// Production tasks
// ======================================================================================================

// Clean dist build directory
gulp.task('clean-dist', function () {
  del(['./dist']);
});

// Build custom and third party Sass/Css
gulp.task('css-prod', function () {
  return gulp.src('./app/scss/application.scss')
    .pipe(sass({
      errLogToConsole: true,
      // includePaths: ['bower_components/susy/sass']
      includePaths: ['styles'].concat(neat)
    }))
    .pipe(autoprefixer({
      cascade: false
    }))
    .pipe(cleanCss({keepBreaks: false}))
    .pipe(rename('application.min.css'))
    .pipe(gulp.dest('./dist'));
});

// Compile compressed vendor build
gulp.task('css-vendor-prod', function () {
  return gulp.src(bowerFiles({
      checkExistence: true,
      filter: '**/*.css'
    }))
    .pipe(concat('vendor.css'))
    .pipe(cleanCss({keepBreaks: false}))
    .pipe(rename('vendor.min.css'))
    .pipe(gulp.dest('./dist'))
});

// Build JS files
gulp.task('js-prod', function () {
  return gulp.src(['./app/js/**/*.js'])
    .pipe(concat('application.js'))
    .pipe(ngAnnotate())
    .pipe(uglify())
    .pipe(rename('application.min.js'))
    .pipe(gulp.dest('./dist'))
});

// Compile compressed vendor build
gulp.task('js-vendor-prod', function () {
  return gulp.src(bowerFiles({
      checkExistence: true,
      filter: '**/*.js'
    }))
    .pipe(concat('vendor.js'))
    .pipe(uglify())
    .pipe(rename('vendor.min.js'))
    .pipe(gulp.dest('./dist'))
});

// Inject production assets into html
gulp.task('inject-production-assets', function () {
  return gulp.src('./app/index.html')
  .pipe(inject(gulp.src(['./dist/application.min.css','./dist/vendor.min.css','./dist/application.min.js','./dist/vendor.min.js'], {read: false})))
  .pipe(gulp.dest('./dist'));
});

// ======================================================================================================
// Main tasks
// ======================================================================================================

// Development server with livereload
gulp.task('default', function () {
  runSequence('clean-dev','css-dev', 'js-lint', 'inject-dev-assets', 'browser-sync', 'watch');
});

// Compile production build
gulp.task('build-production', function () {
  runSequence('clean-dist', 'css-prod', 'css-vendor-prod', 'js-prod', 'js-vendor-prod', 'inject-production-assets');
});
kaumac commented 8 years ago

I have tried everything, I have no idea as to what can be wrong

marvinhagemeister commented 8 years ago

I would try simplifying your watch task first. Generally speaking one should not use BrowserSyncs watch and gulp watch at the same time. In your case you can easily remove all occurences of Browsersync.watch in your tasks. This is probably not the root cause of your problem but it should simplify further debugging

renestalder commented 8 years ago

Couldn't get it working yet with any of those workarounds here. I'm sure it worked before. Could really be an issue of OSX El Capitan. Permission change didn't work but I don't have a default setup so I would be cool if someone explain me why it needs permissions on those folders.

JeremyEnglert commented 8 years ago

I'm having a similar issue. I was able to somewhat fix it by adding the 'file' option. However, this feels weird as it is essentially telling it to "watch" the same file twice (unless I'm understanding this wrong).

// Run BrowserSync and watch for file changes
gulp.task('browser-sync', function() {

    browserSync.init({
        files: ["./assets/css/*.css"],
        proxy: "localhost:8888/jointswp-github/"
    });

    gulp.watch('./assets/scss/**/*.scss', ['styles']);

});

This only works when browserSync is "running". .pipe(browserSync.stream() still isn't injecting. This task runs, but the styles are not injected:

// Compile Sass, Autoprefix and minify
gulp.task('styles', function() {
  return gulp.src('./assets/scss/**/*.scss')
    .pipe(plumber(function(error) {
            gutil.log(gutil.colors.red(error.message));
            this.emit('end');
    }))
    .pipe(sass())
    .pipe(autoprefixer({
            browsers: ['last 2 versions'],
            cascade: false
        }))
    .pipe(gulp.dest('./assets/css/'))
    .pipe(rename({suffix: '.min'}))
    .pipe(minifycss())
    .pipe(gulp.dest('./assets/css/'))
    .pipe(browserSync.stream({match: '**/*.css'}));
});   
alxndrmlr commented 8 years ago

We just solved this but it was due to a caching issue (we modify the css file names for links and then have an RewriteRule to resolve them)

/**
 *  Given a file, e.g. /css/base.css, replaces it with a string containing the
 *  file's mtime, e.g. /css/base.1221534296.css.
 *  See /app/.htaccess for the server rewrite rule that accompanies this function.
 *
 *  @param $file  The file to be loaded.  Must be an absolute path (i.e.
 *   starting with slash).
 */
function auto_version($file) { ... }

We simply removed our auto_versioning when in development mode and the issues was immediately resolve. While this is unique to our setup I'm mentioning it here so as to encourage others to consider that caching and their app is setup.

In our case the base.css file was being updated during the gulp-task, but since the browser had a to base.1221534296.css it seems that browser-sync wasn't able to know what css file to sync.

danieltorscho commented 8 years ago

I don't know what you have done there exactly, but mine is still not working. Tried multiple combinations + your suggestions also.

ZdendRedfox commented 8 years ago

After hours of suspecting BrowserSync as a culprit, finally solved this with disabling cache on my Apache server. Just add the following EnableSendfile off in your apache.conf or http.conf (/etc/apache2/apache.conf) and restart your server.

danieltorscho commented 8 years ago

@ZdendRedfox - still the same, in console output it's showing "[BS] Reloading Browsers..." but the code is not injected, no message popups in the right top corner. By the way, EnableSendfile was already off.

ZdendRedfox commented 8 years ago

I guess in your case it's different. You should see the files that were changed and injected. If you don't see it I guess it's due to your regexp expression for files that should be watched. In my case, I got the message about injection but because BrowserSync proxy replaces proxied URL to localhost:3000 for all occurrences in your HTML, all the assets from localhost:3000 were cached by Apache, however when I accessed my original URL let's say http://mywordpressapp.dev that was proxied, assets were up-to-date.

akmur commented 8 years ago

Just to add more noise to the discussion, I am working on a PHP website and I tried the apache thing but it doesn't seem to make a difference. In my case the style is injected, but then a reload is triggered. Sometimes I see the spinner icon in the Chrome's tab, but no actual reload happens. Some other time, it also reloads.

Fettabachi commented 8 years ago

This solved the problem for me. I'm running El Capitan and was having the same problem coding a Wordpress site. The README file states "Browsersync works by injecting an asynchronous script tag (<script async>...</script>) right after the <body> tag during initial request. In order for this to work properly the <body> tag must be present..."

After looking at the code, I found that there were two conditional tags targeting the body tag in order to add classes for different versions of IE. Removing those statements solved the problem for me because the browsersync script was being appended to the body tag in the first conditional statement.

Your code should be similar to this;

<body>
    <script type="text/javascript" id="__bs_script__">
    //<![CDATA[
    document.write("<script async src='/browser-sync/browser-sync-client.2.11.1.js'><\/script>".replace("HOST", location.hostname));
    //]]>
    </script>
    <script async="" src="/browser-sync/browser-sync-client.2.11.1.js"></script>

My gulpfile.js function looks like this;

// BrowserSync
gulp.task('browser-sync', function () {
   var files = [
      'style.css',
      'ui/**/*.png',
      'js/**/*.js',
      '**/*.php'
   ];

   browserSync.init(files, {
      proxy: 'my-local-site'
   });
});
akmur commented 8 years ago

I managed to fix this issue

Check out my repo, I had issues pasting the code :)

https://github.com/akmur/WPGulp/blob/master/gulpfile.js

arkroy commented 8 years ago

Nopes, tried the same thing, doesn't work. Anyone figure this out yet?? @akmur

// ===========================================
// 15. WATCH CHANGES
// ===========================================
gulp.task('build-watch', function() {
    gulp.watch(config.styles.in, ['styles'], browserSync.reload)
    gulp.watch(config.scripts.in, ['scripts'], browserSync.reload)
    gulp.watch(config.html.templatesIn, ['html'], browserSync.reload)
    gulp.watch(config.html.partialsIn, ['components'], browserSync.reload)
    console.log('Watching...');
});

gulp.task('watch', ['build-watch']);

// ===========================================
// 16. SERVE
// ===========================================
gulp.task('serve', ['build-dev'], function(){
    if(browserSync.active){
        return;
    }
    browserSync.init({
            server: {
                baseDir: config.build.dest,
                index: "index.tpl.html"
            },
            files: [config.build.source + '**/*.*'],
            reloadDelay: 1000,
            ghostMode: {
                clicks: true,
                location: true,
                forms: true,
                scroll: true
            },
            injectChanges: true,
            logFileChanges: true,
            logLevel: 'debug',
            logPrefix: 'fti-patterns',
            notify: true
    });
    gulp.task('watch', ['build-watch']);
});
akmur commented 8 years ago

What I can add is that one thing which was driving me nuts was that browsersync was also watching for css maps, hence reloading when a new one was created, make sure you are not doing the same mistake

Minasokoni commented 8 years ago

On El Capitan: Ran: sudo chown -R $(whoami):admin /usr/local The reason BS reloads is because its firing off the generated souremaps. To prevent BS from reloading instead of injecting the CSS, browserSync.stream( {match: '**/*.css' } ) is required

My Code:

var gulp = require( 'gulp' );
var postcss = require( 'gulp-postcss' );
var autoprefixer = require( 'autoprefixer' );
var sass = require( 'gulp-sass' );
var sourcemaps = require( 'gulp-sourcemaps' );
var plumber = require( 'gulp-plumber' );
var notify = require( 'gulp-notify' );
var browserSync = require( 'browser-sync' );
var plumberErrorHandler = {
    errorHandler: notify.onError( {
        title: 'Gulp',
        message: 'Error: <%= error.message %>'
    } )
};
gulp.task( 'browser-sync', function () {
    var files = [
    '../**/*.php',
    '../js/*js'
    ];
    browserSync.init( files, {
        proxy: "localhost",
        notify: true,
        open: false
    } );
} );
gulp.task( 'sass', function () {
    gulp.src( '../sass/**/*.scss' ).pipe( sourcemaps.init() ).pipe( plumber( plumberErrorHandler ) ).pipe( sass() ).pipe( postcss( [ autoprefixer( {
        browsers: [ 'last 2 versions' ]
    } ) ] ) ).pipe( sourcemaps.write() ).pipe( gulp.dest( '../css' ) ).pipe( browserSync.stream( {
        match: '**/*.css' 
    } ) );
} );
gulp.task( 'default', [ 'sass', 'browser-sync' ], function () {
    gulp.watch( "../sass/**/*.scss", [ 'sass' ] );
} );
acidjazz commented 8 years ago

Just found this thread while having the same issue, even though browserSync reloads the CSS, my browser cache was enabled even w/ my inspector loaded, i hit disable cache under the inspectors network tab, problem solved

frob commented 8 years ago

I had the same issue, can someone explain why this is a permissions issue?

SalathielGenese commented 8 years ago

After many iterations, I got this gulp file:

+function(del, path, gulp, sass, rename, uglifycss, sourcemaps, browserSync)
{
    'use strict';
    gulp.task('clean-css', () => del([
        'web/css/*.css', 'web/css/**/*.css',
        'web/css/*.css.map', 'web/css/**/*.css.map',
        'web/libs/reset/css/*.css', 'web/libs/reset/css/**/*.css',
        'web/libs/reset/css/*.css.map', 'web/libs/reset/css/**/*.css.map'
        ]));
    gulp.task('minify-css', () => gulp.src([
        'web/css/*.css', 'web/css/**/*.css',
        '!web/css/*.min.css', '!web/css/**/*.min.css',
        'web/libs/reset/css/*.css', 'web/libs/reset/css/**/*.css',
        '!web/libs/reset/css/*.min.css', '!web/libs/reset/css/**/*.min.css'
        ]).pipe(sourcemaps.init('.')).pipe(uglifycss()).pipe(rename({suffix: '.min'})).pipe(sourcemaps.write('.')).pipe(gulp.dest(function(file)
            {
                return path.join(path.dirname(file.path), '../css');
            })));
    gulp.task('compile-css', () => gulp.src([
        'web/scss/*.scss', 'web/scss/**/*.scss',
        'web/libs/reset/scss/*.scss', 'web/libs/reset/scss/**/*.scss'
        ]).pipe(sourcemaps.init('.')).pipe(sass()).pipe(sourcemaps.write('.')).pipe(gulp.dest(function(file)
            {
                return path.join(path.dirname(file.path), '../css');
            })));
    gulp.task('build-css', gulp.series('clean-css', 'compile-css', 'minify-css'));
    gulp.task('watch-scss', () => gulp.watch(['web/scss/*.scss', 'web/scss/**/*.scss', 'web/libs/reset/scss/*.scss', 'web/libs/reset/scss/**/*.scss'], gulp.series('build-css')));
    gulp.task('default', gulp.parallel('watch-scss', function(fulfill)
        {
            browserSync.init(null, {proxy: 'localhost:3000'});
            gulp.watch(['web/scss/*.scss', 'web/scss/**/*.scss', 'web/libs/reset/scss/*.scss', 'web/libs/reset/scss/**/*.scss'], gulp.series('build-css', browserSync.reload));
            fulfill();
        }));
}(require("del"), require("path"), require('gulp'), require('gulp-sass'), require('gulp-rename'), require('gulp-uglifycss'), require('gulp-sourcemaps'), require('browser-sync').create());

It refreshes after the first change only. Not nice at all.

SalathielGenese commented 8 years ago

I've just found that I misused browserSync.reload with gulp#4.0... So the fixed update is

+function(del, path, gulp, sass, rename, uglifycss, sourcemaps, browserSync)
{
    'use strict';
    gulp.task('clean-css', () => del([
        'web/css/*.css', 'web/css/**/*.css',
        'web/css/*.css.map', 'web/css/**/*.css.map',
        'web/libs/reset/css/*.css', 'web/libs/reset/css/**/*.css',
        'web/libs/reset/css/*.css.map', 'web/libs/reset/css/**/*.css.map'
        ]));
    gulp.task('minify-css', () => gulp.src([
        'web/css/*.css', 'web/css/**/*.css',
        '!web/css/*.min.css', '!web/css/**/*.min.css',
        'web/libs/reset/css/*.css', 'web/libs/reset/css/**/*.css',
        '!web/libs/reset/css/*.min.css', '!web/libs/reset/css/**/*.min.css'
        ]).pipe(sourcemaps.init('.')).pipe(uglifycss()).pipe(rename({suffix: '.min'})).pipe(sourcemaps.write('.')).pipe(gulp.dest(function(file)
            {
                return path.join(path.dirname(file.path), '../css');
            })));
    gulp.task('compile-css', () => gulp.src([
        'web/scss/*.scss', 'web/scss/**/*.scss',
        'web/libs/reset/scss/*.scss', 'web/libs/reset/scss/**/*.scss'
        ]).pipe(sourcemaps.init('.')).pipe(sass()).pipe(sourcemaps.write('.')).pipe(gulp.dest(function(file)
            {
                return path.join(path.dirname(file.path), '../css');
            })));
    gulp.task('build-css', gulp.series('clean-css', 'compile-css', 'minify-css'));
    gulp.task('watch-scss', () => gulp.watch(['web/scss/*.scss', 'web/scss/**/*.scss', 'web/libs/reset/scss/*.scss', 'web/libs/reset/scss/**/*.scss'], gulp.series('build-css')));
    gulp.task('default', gulp.series('build-css', function(fulfill)
        {
            browserSync.init({proxy: 'localhost:3000'});
            gulp.watch(['web/css/*.min.css', 'web/css/**/*.min.css', 'web/libs/reset/css/*.min.css', 'web/libs/reset/css/**/*.min.css'], function(fulfill)
                {
                    return (browserSync.reload() || true) && fulfill();
                });
            fulfill();
        }, 'watch-scss'));
}(require("del"), require("path"), require('gulp'), require('gulp-sass'), require('gulp-rename'), require('gulp-uglifycss'), require('gulp-sourcemaps'), require('browser-sync').create());
roubaobaozi commented 8 years ago

I second the thought that it has something to do with El Capitan.

I have my project in a bitbucket repository, so I know the code is exactly the same, but browsersync + nodemon doesn't work when run on El Capitan, though it works when run on Windows 8.

Considering nodemon alone works fine on both platforms, BrowserSync alone works fine on both platforms, but BrowserSync doesn't work when paired with nodemon on El Capitan, makes me think the issue isn't with El Capitan, but with BrowserSync?

EDIT: I tested the same code on my 2011 iMac (mid-2011 [iMac12,2],) also on El Capitan, and it works … so I'm stumped. My previous attempt above was tried on my 2011 Mac Book Pro (early 2011 [MacBookPro8,2]) but doesn't ...

v3nt commented 8 years ago

a bit off topic except i use el capitan and the sales have always injected themselves without reloading the page. Problem is if the css is injected I've always lots the source map data in the browser inspector. Does anyone else experience this issue?

remove-akk commented 8 years ago

get this bug on Mac el capitan and on Ubuntu 16.04. browser-sync version 2.14.0

tried use reloadDelay option for browser-sync, but without result but after I downgrade browser-sync version to 2.12.5 - problem solved!

codedbypaul commented 8 years ago

Any update on this?

I've tried all the fixes above but can't get injecting to work. Thought i'd try the files option but that doesn't inject anything either.

When looking at the UI for my site i noticed it looks like the browser is disconnecting after loading the page.

GodLesZ commented 7 years ago

Just to share my solution - I'm also using BS and had problems in proxy-mode. I've tried different solutions and didn't got it to inject the CSS after SASS compilation. After debugging the code, I found my problem(s).

  1. Don't use { once: true } in the stream method. This always results in a browser reload. Don't know, if this is a feature.

  2. You have to use the match-options to ensure BS dosen't trigger for sourcemaps or after things (couldn't find a whitelist yet)

  3. match uses the npm module micromatch and therefore glob-patterns. This is important to know. The given pattern on match must always have a path (sic!) For a wildcard path you may use Example: `{ match: '/*.css' }`

Important: Again, { match: '*.css' } will never trigger at this point! (check for reload or inject) You really have to use a path.

  1. Nothing more. So my mistake was first to use the once-options and second a wrong glob-pattern. Maybe someone had the same problems.. ;)

PS: Just to prove..

jaegz commented 7 years ago

This fixed my issue of having to refresh the page twice to see style and script changes. Now it just injects styles instead of refreshing - as it should.

Make sure you have a / at end of baseDir

gulp.task( 'browser-sync', function() {
    browserSync.init({
        server: {
            baseDir: './public/'
        },
        notify: {
                styles: {
                top: 'auto',
                bottom: '0'
                }
        },
        injectChanges: true
    });
});

Environment Details npm 4.1.2 node 6.9.4 win32 x64 (windows 7) gulp 3.9.1 browser-sync 2.18.7

thomasfrobieter commented 7 years ago

I am new to Gulp and all this stuff, searched and tested for hours now, but i still have one last problem. Currently i just test it by calling "gulp browser-sync" directly - so i should have no side effects with other tasks.

In my case its a remote dev server, not a local one.

If i save the CSS file, i get the message "Injected global.styles.css", the page flashes up for a second (not reloading), but my changes won't appear. Command line says "[BS] File event [change] : css/global.styles.css".

gulp.task('browser-sync', function(cb){
  browserSync('css/global.styles.css', { 
    proxy: "http://dev.server.de/",
    // startPath: "/index.php",
    // port: 8080,
    notify: true,
    open: true,
    ghostMode: {
        clicks: false,
        location: false,
        forms: false,
        scroll: false
    }
  }, cb);
});

Any ideas what's wrong? :(

Running node 6.10.0, CLI 1.2.2, Gulp 4.0.0-alpha.2 on Windows 10 64-Bit, Firefox 51.0.1

rku4er commented 7 years ago

Hey guys, those who don't understand why BrowserSync doesn't apply your changes, make sure your files has proper owner and access permissions.

shakyShane commented 7 years ago

@thomasfrobieter does the file global.styles.css exist the actual webpage? or is it named differently there?

thomasfrobieter commented 7 years ago

@shakyShane Yes, the file exist and has the same filename:

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

and it's already replaced with:

<link rel="stylesheet" type="text/css" href="http://localhost:3000/themes/customer_theme/css/global.styles.css?rel=1488381558329">

The path currently points to the webserver (while localhost:3000 is just the proxy). In this case i do not want to upload the file to the webserver while using browser sync (so i can test style changes localy). I think i have to change this to the UNC path (Windows Network), so all devices can access the synced / changed files via local network. If this is even possibly o.O .. I will report.

Thank you so far! :) This helps me already further.

thomasfrobieter commented 7 years ago

Finally, i got it to work. I configured a simple local webserver pointing at the local files - so i can do the following:

gulp.task('browser-sync', function(cb){
  browserSync('css/styles.css', {
    proxy: "http://dev.remoteserver.tld/",
    rewriteRules: [
        {
            match: new RegExp("/PATH_ON_THE_WEBSERVER/css/styles.css"),
            fn: function() {
                return "http://192.168.2.101:180/PATH_ON_THE_LOCAL_SERVER/css/styles.css"
            }
        }
    ],
    files: "css/*.css",
    serveStatic: ['./css'],
    // Debugging
    logConnections: true,
    logLevel: "debug"
  }, cb);
});
SeanConnell93 commented 7 years ago

calling the on change worked for me

gulp.watch("css/*.scss", ['styles']).on('change', browserSync.reload);

snoopdouglas commented 7 years ago

+1 for @Fettabachi - just had the exact same problem, fixed by swapping the order of my conditional comments.

Would be worth checking that the body tag that the <script> is appended to is not commented out.

ghost commented 7 years ago

I had a similar issue. But in my case my main css file was imported instead of placed as link.

kevinmamaqi commented 7 years ago

@snoopdouglas what do you mean by swapping the order of the conditional comments?

snoopdouglas commented 7 years ago

@kevinmamaqi I can't remember, this was 6 months ago! It was referring to this comment

kevinmamaqi commented 7 years ago

Do you remember how you solved it? It is not specified in the comment @snoopdouglas @Fettabachi

petergus commented 6 years ago

I am running a MAMP site and this worked for me

//define task
gulp.task('bsync', function () {
    //spin up dev server
    browserSync.init({
      proxy: "dev.sitename.local",
      hostname: "dev.sitename.local",
      port: 3000, //even if apache is running on 80 or something else
    });

    //when css files change, reload browserSync 
    gulp.watch('./css/*.css').on('change', function () {
        browserSync.reload();
    });

});

//call task with 'gulp runbsync'
gulp.task('runbsync', ['bsync']);

https://gist.github.com/petergus/31d75a5145e062d4eaa42eb04ce23aea

kentr commented 4 years ago

This worked for me

Add a touch step in the pipeline of the stylesgulp task, using gulp-touch-fd.

// Add `gulp-touch-fd` as dependency first.
var touch = require('gulp-touch-fd');

// Add `touch` step right after the `gulp.dest()` step.
gulp.task( 'some-task', function() {
    ... other build steps ...
    .pipe( gulp.dest( cssPath ) )
    .pipe(touch());

Environment

MacOS High Sierra Browsersync proxied to a vagrant box

Background on what this does: https://github.com/gulpjs/gulp/issues/1461

mcelligottnick commented 4 years ago

I had multple style file inclusions in my HTML, some with the same file name, but different paths, all but one of which were being compiled by gulp. My compiled file compiled/style.css was linked in the HTML below all the others.

<!-- non-compiled CSS files, eg vendor libs -->
<link rel="stylesheet" src="http://localhost:3089/vendor/style.css" type="text/css" media="all">

<!-- My compiled CSS file from Gulp SASS -->
<link rel="stylesheet" src="http://localhost:3089/compiled/style.css" type="text/css" media="all">

When browsersync would run, it would update the querystring of the topmost CSS file changing it to something like

<!-- non-compiled CSS files, eg vendor libs -->
<link rel="stylesheet" src="http://localhost:3089/vendor/style.css?browsersync=1603769772973" type="text/css" media="all">

<!-- My compiled CSS file from Gulp SASS -->
<link rel="stylesheet" src="http://localhost:3089/compiled/style.css" type="text/css" media="all">

And this would cause a reload of the vendor file, which was useless since it hasn't changed and didn't update my compiled compiled/style.css file.

Moving the compiled file link inclusion to the top of all the style file includes seemed to work (or removing the other style includes).

Not sure why, perhaps BS is looking for the top style file which matches the name only, and doesn't care about the path.