gulp-sass autoprefix sourcemap
Asked Answered
A

3

11

This weekend I started playing around with gulp. I wanted to set up a task which can

  • compile my sass files
    • keep working if I make mistakes in the sass file
    • work with sass Bootstrap
  • generate sourcemaps
  • append browser prefixes
  • inject the compiled css wihtout browser reload
  • fast (1-2 s top in dev env)

I got most of the steps but browser prefixes gave me a hard time Here is what I got so far

var browserSync = require('browser-sync');
var reload = browserSync.reload;
var filter = require('gulp-filter');
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var notify = require("gulp-notify");
var sourcemaps = require('gulp-sourcemaps');
var concat = require('gulp-concat');

var config = {
    sassPath: './sass',
    bower: './bower_components',
    bootstrap: './bower_components/bootstrap-sass-official/assets/stylesheets',
    fonts: './bower_components/bootstrap-sass-official/assets/fonts'
};

gulp.task('sass', function () {
    return gulp.src(config.sassPath + '/**/*.scss')
        .pipe(sourcemaps.init())
            .pipe(sass({
                //outputStyle: 'compressed',
                outputStyle: 'nested',
                precision: 10,
                includePaths: [
                    config.sassPath,
                    config.bower,
                    config.bootstrap
                ],
                onError: function (err) {
                    notify().write(err);
                }
            }))
            .pipe(concat('app.css'))
            .pipe(autoprefixer('last 2 version'))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('css'))
        .pipe(filter('**/*.css')) // Filtering stream to only css files
        .pipe(browserSync.reload({stream:true}));
});

gulp.task('browser-sync', function() {
    browserSync({
        logLevel: "info",
        server: {
            baseDir: './',
            //directory: true,
            routes: {
                "/fonts": config.fonts
            }
        }
    });
});

gulp.task('default', ['sass', 'browser-sync'], function () {
    gulp.watch(['./**/*.html', 'js/**/*.js'], reload);
    gulp.watch('sass/*.scss',['sass']);
});

The problem is that the autoprefixer gives me an error and messes up the sourcemaps

The error I get: "gulp-sourcemap-write: source file not found:C:\WEB\skilldrill_v1\skilldrill\sass\app.css"

So for some reason it tries to find the css files in the sass dir

[Edit]
I managed to locate the problem, but couldn't solve it yet. The pipe this thing works: gulp-autoprefixer -> do some stuff -> prefixing tasks -> vinyl-sourcemaps-apply

On the 35th line of gulp-autoprefixer\index.js: applySourceMap(file, res.map.toString()); From this point the vinyl-sourmaps-apply understands that the current file (in my case app.css) becomes a source too.

Here are the problems: a) it thinks that the css file is in the same folder as specified in gulp.src() which is usually not true b) it doesn't work only with the lines added by the autoprefixer, but adds reference to every single line

Do you have any ideas based on this information ? I started digging in the gulp-concat which handles a similar issue properly.

Audiophile answered 5/10, 2014 at 13:39 Comment(1)
I think I have had a similar issue as you with sourcemaps and gulp-autoprefixer. I also tried a work around method, running the sourcemaps twice. What I have recently found is using PostCSS with CSSNext seems to solve the issue. Have a look here to see if the solution is useful for you.Kebab
K
6

I've had the same issues with autoprefixer and sourcemaps. I've changed my workflow to create sourcemaps after compiling sass, then loading into gulp-sourcemaps again when I run autoprefixer, and finally creating updated sourcemaps.

// Compile Sass
.pipe(sourcemaps.init())
    .pipe(sass())
.pipe(sourcemaps.write())
.pipe(gulp.dest('../public/assets/css'))

// Autoprefix
.pipe(sourcemaps.init({loadMaps: true}))
    .pipe(autoprefixer('last 2 version', 'ie 8', 'ie 9'))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('../public/assets/css'))

And then only watching css files for style injection.

// CSS Injection
.pipe(filter('**/*.css'))
.pipe(browserSync.reload({stream:true}))
Keir answered 2/12, 2014 at 21:3 Comment(0)
L
0

I know this is an old question, but for those who come here today:

I had no problems to get Sourcemaps and AutoPrefixer working together. So it looks as if this issue has been fixed. The following setup is what works for me:

const
    gulp = require('gulp'),
    sass = require('gulp-sass'),
    autoprefixer = require('gulp-autoprefixer'),
    concat = require('gulp-concat'),
    sourcemaps = require('gulp-sourcemaps'),
    browserSync = require('browser-sync').create();

var
    scssSourcePath = './css/**/*.scss',
    cssDestPath = './css/',
    cssDestFile = 'styles.css';


// Task 'styles': 
// Compile SASS to CSS
gulp.task('styles', function () {
    return gulp.src(scssSourcePath)
        .pipe(sourcemaps.init())
        .pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError))
        .pipe(autoprefixer())
        .pipe(concat(cssDestFile))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(cssDestPath))
        .pipe(browserSync.stream());
    });


// Default task: 
// Init Browser-Sync,
// Watch folders and start tasks on change
gulp.task('default', function () {
    browserSync.init({
        server: "."
    });

    return gulp.watch(scssSourcePath, gulp.series('styles'));
});

Side note:
Instead of Autoprefixer I actually recommend to use CSSnano. It includes Autoprefixer and does even more optimizations. Simply replace all occurrences of autoprefixer in the above code with cssnano and you will have that additional benefit.

Lone answered 26/11, 2019 at 14:38 Comment(0)
A
-1

@philipb3 THANK YOU!! Spent the better part of 2 days trying to figure out why autoprefixer and gulp-sourcemaps weren't playing well together, then when I finally fixed that issue, browser-sync would fully reload, but wasn't injecting newly generated css. This seems to have resolved the issue.

For those who are confused as was I at first from the explanation, here is a sample of my sass task in my gulp file with comments on what's happening.

gulp.task('sass', function() {
    // create postcss processors
    var processors = [
        mqpacker,
        autoprefixer({ browsers: ['last 2 version'] })
    ];

return gulp.src(src.scss)
   .pipe(sourcemaps.init()) // start sourcemaps
   .pipe(sass({ outputStyle: 'expanded' }).on('error', sass.logError)) // compile sass
   .pipe(sourcemaps.write()) // write map inline
   .pipe(gulp.dest(src.css)) // pipe to css dir
   .pipe(sourcemaps.init({loadMaps: true})) // init sourcemaps again after pipe to dest dir
   .pipe(postcss(processors)) // run postcss stuff
   .pipe(sourcemaps.write('./maps')) // write map to external dir instead of inline
   .pipe(gulp.dest(src.css)) // pipe to dest dir again
   .pipe(filter('**/*.css')) // filter out everything that isn't a css file
   .pipe(reload({ stream: true })); // pipe result to browser-sync for reload
});

Edit: So eventually this also started to break again when I started adding some more tasks and plugins to my gulp build. I'm not entirely sure that it's necessary to load sourcemaps twice. I've rebuilt my gulp file, starting with gulp-sass and gulp-sourcemaps and this seems to work for me even after configuring other tasks after. Hope one of these two solutions will work for someone.

Relevant Plugins:

var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');

//** Post CSS Modules **//
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var mqpacker = require('css-mqpacker');

If you're using browser-sync: (also set up watch/serve tasks)

//** Browser-Sync **//
var browserSync = require('browser-sync').create();
var reload = browserSync.reload;

Sources: change these accordingly

var src = {
   base: 'ROOT_FOLDER',
   js:     'ROOT_FOLDER/js/**/*.js',
   css:    'ROOT_FOLDER/css',
   html:   'ROOT_FOLDER/*.html',
   jsdir:  'ROOT_FOLDER/js',
   maps:   './maps',
   scss:   'ROOT_FOLDER/scss/**/*.scss'
};

Task

gulp.task('sass', function () {
    // load post-css plugins
    var processors = [
        mqpacker,
        autoprefixer({
            browsers: ['last 2 version']
        })
    ];
    // start sass task
    return gulp.src(src.scss)
      .pipe(sourcemaps.init()) // init sourcemaps
      .pipe(sass.sync({outputStyle: 'expanded'}).on('error', sass.logError)) // compile scss
      .pipe(postcss(processors)) // autoprefix and combine media queries
      .pipe(sourcemaps.write(src.maps)) // write emaps relative to source dir
      .pipe(gulp.dest(src.css)) // pipe to css folder
      .pipe(browserSync.stream()); // send stream to browser-sync task
});
Assurbanipal answered 19/2, 2016 at 19:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.